diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-12 14:27:29 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-13 09:35:20 +0000 |
commit | c30a6232df03e1efbd9f3b226777b07e087a1122 (patch) | |
tree | e992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/components/browser_ui | |
parent | 7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff) | |
download | qtwebengine-chromium-85-based.tar.gz |
BASELINE: Update Chromium to 85.0.4183.14085-based
Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/components/browser_ui')
268 files changed, 11291 insertions, 313 deletions
diff --git a/chromium/components/browser_ui/android/bottomsheet/BUILD.gn b/chromium/components/browser_ui/android/bottomsheet/BUILD.gn index a9965b2f22d..f43f2943228 100644 --- a/chromium/components/browser_ui/android/bottomsheet/BUILD.gn +++ b/chromium/components/browser_ui/android/bottomsheet/BUILD.gn @@ -2,11 +2,47 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import("//build/config/android/config.gni") import("//build/config/android/rules.gni") +import("//chrome/android/features/android_library_factory_tmpl.gni") android_library("java") { - sources = [ "java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetContent.java" ] + sources = [ + "java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetContent.java", + "java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetController.java", + "java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetObserver.java", + "java/src/org/chromium/components/browser_ui/bottomsheet/EmptyBottomSheetObserver.java", + ] - deps = [ "//third_party/android_deps:androidx_annotation_annotation_java" ] + deps = [ + ":java_resources", + "//components/browser_ui/widget/android:java", + "//third_party/android_deps:androidx_annotation_annotation_java", + "//ui/android:ui_java", + ] +} + +android_resources("java_resources") { + custom_package = "org.chromium.components.browser_ui.bottomsheet" + sources = [ + "java/res/layout/bottom_sheet.xml", + "java/res/values/dimens.xml", + ] + + deps = [ "//components/browser_ui/strings/android:browser_ui_strings_grd" ] +} + +# The only dependent on this code outside of this component should be glue. +android_library("manager_java") { + sources = [ "java/src/org/chromium/components/browser_ui/bottomsheet/ManagedBottomSheetController.java" ] + + deps = [ ":java" ] +} + +android_library_factory("factory_java") { + sources = [ "internal/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetControllerFactory.java" ] + + deps = [ + ":java", + ":manager_java", + ] } diff --git a/chromium/components/browser_ui/android/bottomsheet/DEPS b/chromium/components/browser_ui/android/bottomsheet/DEPS new file mode 100644 index 00000000000..1ff4639a034 --- /dev/null +++ b/chromium/components/browser_ui/android/bottomsheet/DEPS @@ -0,0 +1,7 @@ +noparent = True +include_rules = [ + "+base/android", + "+base/test/android", + "+components/browser_ui/widget/android", + "+ui/android", +] diff --git a/chromium/components/browser_ui/android/bottomsheet/internal/BUILD.gn b/chromium/components/browser_ui/android/bottomsheet/internal/BUILD.gn new file mode 100644 index 00000000000..a81af4a478e --- /dev/null +++ b/chromium/components/browser_ui/android/bottomsheet/internal/BUILD.gn @@ -0,0 +1,44 @@ +# Copyright 2020 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. + +import("//build/config/android/rules.gni") + +android_library("java") { + visibility = [ + ":*", + "../test:*", + "//chrome/android:chrome_all_java", + ] + + sources = [ + "java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheet.java", + "java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetControllerFactory.java", + "java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetControllerImpl.java", + "java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetSwipeDetector.java", + "java/src/org/chromium/components/browser_ui/bottomsheet/TouchRestrictingFrameLayout.java", + ] + + deps = [ + "..:java", + "..:java_resources", + "..:manager_java", + "//base:base_java", + "//components/browser_ui/widget/android:java", + "//third_party/android_deps:androidx_annotation_annotation_java", + "//ui/android:ui_java", + ] +} + +android_library("junit_tests") { + bypass_platform_checks = true + testonly = true + sources = [ "java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetSwipeDetectorTest.java" ] + deps = [ + ":java", + "//base:base_java", + "//base:base_junit_test_support", + "//third_party/junit", + "//third_party/mockito:mockito_java", + ] +} diff --git a/chromium/components/browser_ui/android/bottomsheet/internal/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheet.java b/chromium/components/browser_ui/android/bottomsheet/internal/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheet.java new file mode 100644 index 00000000000..1ced11721f2 --- /dev/null +++ b/chromium/components/browser_ui/android/bottomsheet/internal/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheet.java @@ -0,0 +1,1244 @@ +// Copyright 2017 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.components.browser_ui.bottomsheet; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.ValueAnimator; +import android.content.Context; +import android.graphics.Color; +import android.graphics.Rect; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.view.animation.DecelerateInterpolator; +import android.view.animation.Interpolator; +import android.widget.FrameLayout; + +import androidx.annotation.DimenRes; +import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; + +import org.chromium.base.MathUtils; +import org.chromium.base.ObserverList; +import org.chromium.components.browser_ui.bottomsheet.BottomSheetContent.HeightMode; +import org.chromium.components.browser_ui.bottomsheet.BottomSheetController.SheetState; +import org.chromium.components.browser_ui.bottomsheet.BottomSheetController.StateChangeReason; +import org.chromium.ui.KeyboardVisibilityDelegate; +import org.chromium.ui.util.AccessibilityUtil; + +/** + * This class defines the bottom sheet that has multiple states and a persistently showing toolbar. + * Namely, the states are: + * - PEEK: Only the toolbar is visible at the bottom of the screen. + * - HALF: The sheet is expanded to consume around half of the screen. + * - FULL: The sheet is expanded to its full height. + * + * All the computation in this file is based off of the bottom of the screen instead of the top + * for simplicity. This means that the bottom of the screen is 0 on the Y axis. + */ +class BottomSheet extends FrameLayout + implements BottomSheetSwipeDetector.SwipeableBottomSheet, View.OnLayoutChangeListener { + /** + * The base duration of the settling animation of the sheet. 218 ms is a spec for material + * design (this is the minimum time a user is guaranteed to pay attention to something). + */ + private static final int BASE_ANIMATION_DURATION_MS = 218; + + /** + * The fraction of the way to the next state the sheet must be swiped to animate there when + * released. This is the value used when there are 3 active states. A smaller value here means + * a smaller swipe is needed to move the sheet around. + */ + private static final float THRESHOLD_TO_NEXT_STATE_3 = 0.4f; + + /** This is similar to {@link #THRESHOLD_TO_NEXT_STATE_3} but for 2 states instead of 3. */ + private static final float THRESHOLD_TO_NEXT_STATE_2 = 0.3f; + + /** The height ratio for the sheet in the SheetState.HALF state. */ + private static final float HALF_HEIGHT_RATIO = 0.75f; + + /** The desired height of a content that has just been shown or whose height was invalidated. */ + private static final float HEIGHT_UNSPECIFIED = -1.0f; + + /** A flag to force the small screen state of the bottom sheet. */ + private static Boolean sIsSmallScreenForTesting; + + /** The interpolator that the height animator uses. */ + private final Interpolator mInterpolator = new DecelerateInterpolator(1.0f); + + /** The list of observers of this sheet. */ + private final ObserverList<BottomSheetObserver> mObservers = new ObserverList<>(); + + /** The visible rect for the screen taking the keyboard into account. */ + private final Rect mVisibleViewportRect = new Rect(); + + /** An out-array for use with getLocationInWindow to prevent constant allocations. */ + private final int[] mCachedLocation = new int[2]; + + /** The minimum distance between half and full states to allow the half state. */ + private final float mMinHalfFullDistance; + + /** The height of the shadow that sits above the toolbar. */ + private final int mToolbarShadowHeight; + + /** The view that contains the sheet. */ + private ViewGroup mSheetContainer; + + /** For detecting scroll and fling events on the bottom sheet. */ + private BottomSheetSwipeDetector mGestureDetector; + + /** The animator used to move the sheet to a fixed state when released by the user. */ + private ValueAnimator mSettleAnimator; + + /** The width of the view that contains the bottom sheet. */ + private int mContainerWidth; + + /** The height of the view that contains the bottom sheet. */ + private int mContainerHeight; + + /** The desired height of the current content view. */ + private float mContentDesiredHeight = HEIGHT_UNSPECIFIED; + + /** + * The current offset of the sheet from the bottom of the screen in px. This does not include + * added offset from the scrolling of the browser controls which allows the sheet's toolbar to + * show and hide in-sync with the top toolbar. + */ + private float mCurrentOffsetPx; + + /** The current state that the sheet is in. */ + @SheetState + private int mCurrentState = SheetState.HIDDEN; + + /** The target sheet state. This is the state that the sheet is currently moving to. */ + @SheetState + private int mTargetState = SheetState.NONE; + + /** While scrolling, this holds the state the scrolling started in. Otherwise, it's NONE. */ + @SheetState + int mScrollingStartState = SheetState.NONE; + + /** A handle to the content being shown by the sheet. */ + @Nullable + protected BottomSheetContent mSheetContent; + + /** A handle to the FrameLayout that holds the content of the bottom sheet. */ + private TouchRestrictingFrameLayout mBottomSheetContentContainer; + + /** + * The last offset ratio sent to observers of onSheetOffsetChanged(). This is used to ensure the + * min and max values are provided at least once (0 and 1). + */ + private float mLastOffsetRatioSent; + + /** The FrameLayout used to hold the bottom sheet toolbar. */ + private TouchRestrictingFrameLayout mToolbarHolder; + + /** + * The default toolbar view. This is shown when the current bottom sheet content doesn't have + * its own toolbar and when the bottom sheet is closed. + */ + protected View mDefaultToolbarView; + + /** Whether the {@link BottomSheet} and its children should react to touch events. */ + private boolean mIsTouchEnabled; + + /** Whether the sheet is currently open. */ + private boolean mIsSheetOpen; + + /** Whether {@link #destroy()} has been called. **/ + private boolean mIsDestroyed; + + /** The ratio in the range [0, 1] that the browser controls are hidden. */ + private float mBrowserControlsHiddenRatio; + + /** A means of checking whether accessibility is currently enabled. */ + private AccessibilityUtil mAccessibilityUtil; + + @Override + public boolean shouldGestureMoveSheet(MotionEvent initialEvent, MotionEvent currentEvent) { + // If the sheet is scrolling off-screen or in the process of hiding, gestures should not + // affect it. + if (getCurrentOffsetPx() < getSheetHeightForState(SheetState.PEEK) + || getOffsetFromBrowserControls() > 0) { + return false; + } + + // If the sheet is already open, the experiment is not enabled, or accessibility is enabled + // there is no need to restrict the swipe area. + if (isSheetOpen() || mAccessibilityUtil.isAccessibilityEnabled()) { + return true; + } + + float startX = mVisibleViewportRect.left; + float endX = getToolbarView().getWidth() + mVisibleViewportRect.left; + return currentEvent.getRawX() > startX && currentEvent.getRawX() < endX; + } + + /** + * Constructor for inflation from XML. + * @param context An Android context. + * @param atts The XML attributes. + */ + public BottomSheet(Context context, AttributeSet atts) { + super(context, atts); + + mMinHalfFullDistance = + getResources().getDimensionPixelSize(R.dimen.bottom_sheet_min_full_half_distance); + mToolbarShadowHeight = getResources().getDimensionPixelOffset(getTopShadowResourceId()); + + mGestureDetector = new BottomSheetSwipeDetector(context, this); + mIsTouchEnabled = true; + } + + /** @return The dimen describing the height of the shadow above the bottom sheet. */ + static @DimenRes int getTopShadowResourceId() { + return R.dimen.bottom_sheet_toolbar_shadow_height; + } + + static @DimenRes int getShadowTopOffsetResourceId() { + return R.dimen.bottom_sheet_shadow_top_offset; + } + + /** + * Called when the activity containing the {@link BottomSheet} is destroyed. + */ + void destroy() { + mIsDestroyed = true; + mIsTouchEnabled = false; + mObservers.clear(); + endAnimations(); + } + + /** @param accessibilityUtil A mechanism for testing whether accessibility is enabled. */ + void setAccssibilityUtil(AccessibilityUtil accessibilityUtil) { + mAccessibilityUtil = accessibilityUtil; + } + + /** Immediately end all animations and null the animators. */ + void endAnimations() { + if (mSettleAnimator != null) mSettleAnimator.end(); + mSettleAnimator = null; + } + + /** @return Whether the sheet is in the process of hiding. */ + boolean isHiding() { + return mSettleAnimator != null && mTargetState == SheetState.HIDDEN; + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent e) { + if (!isTouchEventInUsableArea(e) && e.getActionMasked() == MotionEvent.ACTION_DOWN) { + return false; + } + + // If touch is disabled, act like a black hole and consume touch events without doing + // anything with them. + if (!mIsTouchEnabled) return true; + + if (isHiding()) return false; + + return mGestureDetector.onInterceptTouchEvent(e); + } + + @Override + public boolean onTouchEvent(MotionEvent e) { + if (!isTouchEventInUsableArea(e) && e.getActionMasked() == MotionEvent.ACTION_DOWN) { + return false; + } + + // If touch is disabled, act like a black hole and consume touch events without doing + // anything with them. + if (!mIsTouchEnabled) return true; + + mGestureDetector.onTouchEvent(e); + + return true; + } + + @Override + public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + int heightSize = MeasureSpec.getSize(heightMeasureSpec); + assert heightSize != 0; + int height = heightSize + mToolbarShadowHeight; + int mode = isFullHeightWrapContent() ? MeasureSpec.AT_MOST : MeasureSpec.EXACTLY; + super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(height, mode)); + } + + /** + * Adds layout change listeners to the views that the bottom sheet depends on. Namely the + * heights of the root view and control container are important as they are used in many of the + * calculations in this class. + * @param window Android window for getting insets. + * @param keyboardDelegate Delegate for hiding the keyboard. + */ + public void init(Window window, KeyboardVisibilityDelegate keyboardDelegate) { + View root = (View) getParent(); + + mToolbarHolder = + (TouchRestrictingFrameLayout) findViewById(R.id.bottom_sheet_toolbar_container); + mToolbarHolder.setBackgroundResource( + org.chromium.components.browser_ui.styles.R.drawable.top_round); + + mDefaultToolbarView = mToolbarHolder.findViewById(R.id.bottom_sheet_toolbar); + + getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT; + + mBottomSheetContentContainer = + (TouchRestrictingFrameLayout) findViewById(R.id.bottom_sheet_content); + mBottomSheetContentContainer.setBottomSheet(this); + mBottomSheetContentContainer.setBackgroundResource( + org.chromium.components.browser_ui.styles.R.drawable.top_round); + + mContainerWidth = root.getWidth(); + mContainerHeight = root.getHeight(); + + // Listen to height changes on the root. + root.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { + private int mPreviousKeyboardHeight; + + @Override + public void onLayoutChange(View v, int left, int top, int right, int bottom, + int oldLeft, int oldTop, int oldRight, int oldBottom) { + // Compute the new height taking the keyboard into account. + // TODO(mdjones): Share this logic with LocationBarLayout: crbug.com/725725. + int previousWidth = mContainerWidth; + int previousHeight = mContainerHeight; + mContainerWidth = right - left; + mContainerHeight = bottom - top; + + if (previousWidth != mContainerWidth || previousHeight != mContainerHeight) { + if (mCurrentState == SheetState.HALF && !isHalfStateEnabled()) { + setSheetState(SheetState.FULL, false); + } + invalidateContentDesiredHeight(); + } + + int heightMinusKeyboard = (int) mContainerHeight; + int keyboardHeight = 0; + + // Reset mVisibleViewportRect regardless of sheet open state as it is used outside + // of calculating the keyboard height. + window.getDecorView().getWindowVisibleDisplayFrame(mVisibleViewportRect); + if (isSheetOpen()) { + int decorHeight = window.getDecorView().getHeight(); + heightMinusKeyboard = Math.min(decorHeight, mVisibleViewportRect.height()); + keyboardHeight = (int) (mContainerHeight - heightMinusKeyboard); + } + + if (keyboardHeight != mPreviousKeyboardHeight) { + // If the keyboard height changed, recompute the padding for the content area. + // This shrinks the content size while retaining the default background color + // where the keyboard is appearing. If the sheet is not showing, resize the + // sheet to its default state. + mBottomSheetContentContainer.setPadding( + mBottomSheetContentContainer.getPaddingLeft(), + mBottomSheetContentContainer.getPaddingTop(), + mBottomSheetContentContainer.getPaddingRight(), keyboardHeight); + } + + if (previousHeight != mContainerHeight + || mPreviousKeyboardHeight != keyboardHeight) { + // If we are in the middle of a touch event stream (i.e. scrolling while + // keyboard is up) don't set the sheet state. Instead allow the gesture detector + // to position the sheet and make sure the keyboard hides. + if (mGestureDetector.isScrolling() && keyboardDelegate != null) { + keyboardDelegate.hideKeyboard(BottomSheet.this); + } else { + cancelAnimation(); + setSheetState(mCurrentState, false); + } + } + + mPreviousKeyboardHeight = keyboardHeight; + } + }); + + // Listen to height changes on the toolbar. + mToolbarHolder.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { + @Override + public void onLayoutChange(View v, int left, int top, int right, int bottom, + int oldLeft, int oldTop, int oldRight, int oldBottom) { + // Make sure the size of the layout actually changed. + if (bottom - top == oldBottom - oldTop && right - left == oldRight - oldLeft) { + return; + } + + if (!mGestureDetector.isScrolling() && isRunningSettleAnimation()) return; + + setSheetState(mCurrentState, false); + } + }); + + mSheetContainer = (ViewGroup) this.getParent(); + mSheetContainer.removeView(this); + } + + /** @param ratio The current browser controls hidden ratio. */ + void setBrowserControlsHiddenRatio(float ratio) { + mBrowserControlsHiddenRatio = ratio; + + if (getSheetState() == SheetState.HIDDEN) return; + if (getCurrentOffsetPx() > getSheetHeightForState(SheetState.PEEK)) return; + + // Updating the offset will automatically account for the browser controls. + setSheetOffsetFromBottom(getCurrentOffsetPx(), StateChangeReason.SWIPE); + } + + @Override + public void onWindowFocusChanged(boolean hasWindowFocus) { + super.onWindowFocusChanged(hasWindowFocus); + + // Trigger a relayout on window focus to correct any positioning issues when leaving Chrome + // previously. This is required as a layout is not triggered when coming back to Chrome + // with the keyboard previously shown. + if (hasWindowFocus) requestLayout(); + } + + @Override + public boolean isContentScrolledToTop() { + return mSheetContent == null || mSheetContent.getVerticalScrollOffset() <= 0; + } + + @Override + public float getCurrentOffsetPx() { + return mCurrentOffsetPx; + } + + @Override + public float getMinOffsetPx() { + return (swipeToDismissEnabled() ? getHiddenRatio() : getPeekRatio()) * mContainerHeight; + } + + /** + * Test whether a motion event is in the area of the sheet considered to be usable (i.e. not + * on the shadow shown above the sheet or some other decorative part of the view). + * @param e The motion event relative to the bottom sheet view. + * @return Whether the event is considered to be in the usable area of the sheet. + */ + public boolean isTouchEventInUsableArea(MotionEvent event) { + return event.getY() > getToolbarShadowHeight(); + } + + @Override + public boolean isTouchEventInToolbar(MotionEvent event) { + mToolbarHolder.getLocationInWindow(mCachedLocation); + // This check only tests for collision for the Y component since the sheet is the full width + // of the screen. We only care if the touch event is above the bottom of the toolbar since + // we won't receive an event if the touch is outside the sheet. + return mCachedLocation[1] + mToolbarHolder.getHeight() > event.getRawY(); + } + + /** + * @return Whether flinging down hard enough will close the sheet. + */ + private boolean swipeToDismissEnabled() { + return mSheetContent != null ? mSheetContent.swipeToDismissEnabled() : true; + } + + /** + * @return Whether the half state should be skipped when moving the sheet down. + */ + private boolean shouldSkipHalfStateOnScrollingDown() { + return mSheetContent == null || mSheetContent.skipHalfStateOnScrollingDown(); + } + + /** + * @return The minimum sheet state that the user can swipe to. i.e. flinging down will either + * close the sheet or peek it. + */ + @SheetState + int getMinSwipableSheetState() { + return swipeToDismissEnabled() || !isPeekStateEnabled() ? SheetState.HIDDEN + : SheetState.PEEK; + } + + /** + * Get the state that the bottom sheet should open to with the provided content. + * @return The minimum opened state for the current content. + */ + @SheetState + int getOpeningState() { + if (mSheetContent == null) { + return SheetState.HIDDEN; + } else if (isPeekStateEnabled()) { + return SheetState.PEEK; + } else if (isHalfStateEnabled()) { + return SheetState.HALF; + } + return SheetState.FULL; + } + + @Override + public float getMaxOffsetPx() { + return getFullRatio() * mContainerHeight; + } + + /** + * Show content in the bottom sheet's content area. + * @param content The {@link BottomSheetContent} to show, or null if no content should be shown. + */ + @VisibleForTesting + void showContent(@Nullable final BottomSheetContent content) { + // If the desired content is already showing, do nothing. + if (mSheetContent == content) return; + + // Remove this as listener from previous content layout and size changes. + if (mSheetContent != null) { + mSheetContent.setContentSizeListener(null); + mSheetContent.getContentView().removeOnLayoutChangeListener(this); + } + + swapViews(content != null ? content.getContentView() : null, + mSheetContent != null ? mSheetContent.getContentView() : null, + mBottomSheetContentContainer); + + View newToolbar = content != null ? content.getToolbarView() : null; + swapViews(newToolbar, mSheetContent != null ? mSheetContent.getToolbarView() : null, + mToolbarHolder); + + // We hide the default toolbar if the new content has its own. + mDefaultToolbarView.setVisibility(newToolbar != null ? GONE : VISIBLE); + + onSheetContentChanged(content); + } + + /** + * Removes the oldView (or sets it to invisible) and adds the new view to the specified parent. + * @param newView The new view to transition to. + * @param oldView The old view to transition from. + * @param parent The parent for newView and oldView. + */ + private void swapViews(final View newView, final View oldView, final ViewGroup parent) { + if (oldView != null && oldView.getParent() != null) parent.removeView(oldView); + if (newView != null && parent != newView.getParent()) parent.addView(newView); + } + + /** + * A notification that the sheet is exiting the peek state into one that shows content. + * @param reason The reason the sheet was opened, if any. + */ + private void onSheetOpened(@StateChangeReason int reason) { + if (mIsSheetOpen) return; + + mIsSheetOpen = true; + + for (BottomSheetObserver o : mObservers) o.onSheetOpened(reason); + } + + /** + * A notification that the sheet has returned to the peeking state. + * @param reason The {@link StateChangeReason} that the sheet was closed, + * if any. + */ + private void onSheetClosed(@StateChangeReason int reason) { + if (!mIsSheetOpen) return; + mIsSheetOpen = false; + + for (BottomSheetObserver o : mObservers) o.onSheetClosed(reason); + // If the sheet contents are cleared out before #onSheetClosed is called, do not try to + // retrieve the accessibility string. + if (getCurrentSheetContent() != null) { + announceForAccessibility(getResources().getString( + getCurrentSheetContent().getSheetClosedAccessibilityStringId())); + } + clearFocus(); + + setFocusable(false); + setFocusableInTouchMode(false); + setContentDescription(null); + } + + /** + * Cancels and nulls the height animation if it exists. + */ + private void cancelAnimation() { + if (mSettleAnimator == null) return; + mSettleAnimator.cancel(); + mSettleAnimator = null; + } + + /** + * Creates the sheet's animation to a target state. + * @param targetState The target state. + * @param reason The reason the sheet started animation. + */ + private void createSettleAnimation( + @SheetState final int targetState, @StateChangeReason final int reason) { + mTargetState = targetState; + mSettleAnimator = + ValueAnimator.ofFloat(getCurrentOffsetPx(), getSheetHeightForState(targetState)); + mSettleAnimator.setDuration(BASE_ANIMATION_DURATION_MS); + mSettleAnimator.setInterpolator(mInterpolator); + + // When the animation is canceled or ends, reset the handle to null. + mSettleAnimator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animator) { + if (mIsDestroyed) return; + + mSettleAnimator = null; + setInternalCurrentState(targetState, reason); + mTargetState = SheetState.NONE; + } + }); + + mSettleAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animator) { + setSheetOffsetFromBottom((Float) animator.getAnimatedValue(), reason); + } + }); + + setInternalCurrentState(SheetState.SCROLLING, reason); + mSettleAnimator.start(); + } + + /** + * @return Get the height in px that the peeking bar is offset due to the browser controls. + */ + private float getOffsetFromBrowserControls() { + if (mSheetContent == null || !mSheetContent.hideOnScroll() || !isPeekStateEnabled()) { + return 0; + } + + return getPeekRatio() * mContainerHeight * mBrowserControlsHiddenRatio; + } + + /** + * Sets the sheet's offset relative to the bottom of the screen. + * @param offset The offset that the sheet should be. + */ + void setSheetOffsetFromBottom(float offset, @StateChangeReason int reason) { + mCurrentOffsetPx = offset; + + // The browser controls offset is added here so that the sheet's toolbar behaves like the + // browser controls do. + float translationY = (mContainerHeight - mCurrentOffsetPx) + getOffsetFromBrowserControls(); + + if (isSheetOpen() && MathUtils.areFloatsEqual(translationY, getTranslationY())) return; + + setTranslationY(translationY); + + float hiddenHeight = getHiddenRatio() * mContainerHeight; + if (mCurrentOffsetPx <= hiddenHeight && this.getParent() != null) { + mSheetContainer.removeView(this); + } else if (mCurrentOffsetPx > hiddenHeight && this.getParent() == null) { + mSheetContainer.addView(this); + } + + // Do open/close computation based on the minimum allowed state by the sheet's content. + // Note that when transitioning from hidden to peek, even dismissable sheets may want + // to have a peek state. + @SheetState + int minSwipableState = getMinSwipableSheetState(); + if (isPeekStateEnabled() && (!isSheetOpen() || mTargetState == SheetState.PEEK)) { + minSwipableState = SheetState.PEEK; + } + + float minScrollableHeight = getSheetHeightForState(minSwipableState); + boolean isAtMinHeight = MathUtils.areFloatsEqual(getCurrentOffsetPx(), minScrollableHeight); + boolean heightLessThanPeek = getCurrentOffsetPx() < minScrollableHeight; + // Trigger the onSheetClosed event when the sheet is moving toward the hidden state if peek + // is disabled. This should be fine since touch is disabled when the sheet's target is + // hidden. + boolean triggerCloseWithHidden = !isPeekStateEnabled() && mTargetState == SheetState.HIDDEN; + + if (isSheetOpen() && (heightLessThanPeek || isAtMinHeight || triggerCloseWithHidden)) { + onSheetClosed(reason); + } else if (!isSheetOpen() && mTargetState != SheetState.HIDDEN + && getCurrentOffsetPx() > minScrollableHeight) { + onSheetOpened(reason); + } + + sendOffsetChangeEvents(); + } + + @Override + public void setSheetOffset(float offset, boolean shouldAnimate) { + cancelAnimation(); + if (mSheetContent == null) return; + + if (shouldAnimate) { + float velocityY = getCurrentOffsetPx() - offset; + + @SheetState + int targetState = getTargetSheetState(offset, -velocityY); + + setSheetState(targetState, true, StateChangeReason.SWIPE); + } else { + setInternalCurrentState(SheetState.SCROLLING, StateChangeReason.SWIPE); + setSheetOffsetFromBottom(offset, StateChangeReason.SWIPE); + } + } + + /** + * @return The ratio of the height of the screen that the hidden state is. + */ + @VisibleForTesting + float getHiddenRatio() { + return 0; + } + + /** @return Whether the peeking state for the sheet's content is enabled. */ + boolean isPeekStateEnabled() { + return mSheetContent != null && mSheetContent.getPeekHeight() != HeightMode.DISABLED; + } + + /** @return Whether the half-height of the sheet is enabled. */ + private boolean isHalfStateEnabled() { + if (mSheetContent == null) return false; + + // Half state is invalid on small screens, when wrapping content at full height, and when + // explicitly disabled. + return !isSmallScreen() && mSheetContent.getHalfHeightRatio() != HeightMode.DISABLED + && mSheetContent.getFullHeightRatio() != HeightMode.WRAP_CONTENT; + } + + /** @return Whether the height mode for the full state is WRAP_CONTENT. */ + private boolean isFullHeightWrapContent() { + return mSheetContent != null + && mSheetContent.getFullHeightRatio() == HeightMode.WRAP_CONTENT; + } + + /** + * @return The ratio of the height of the screen that the peeking state is. + */ + public float getPeekRatio() { + if (mContainerHeight <= 0 || !isPeekStateEnabled()) return 0; + + // If the content has a custom peek ratio set, use that instead of computing one. + if (mSheetContent != null && mSheetContent.getPeekHeight() != HeightMode.DEFAULT) { + assert mSheetContent.getPeekHeight() + != HeightMode.WRAP_CONTENT : "The peek mode can't wrap content."; + float ratio = mSheetContent.getPeekHeight() / (float) mContainerHeight; + assert ratio > 0 && ratio <= 1 : "Custom peek ratios must be in the range of (0, 1]."; + return ratio; + } + assert getToolbarView() != null : "Using default peek height requires a non-null toolbar"; + + View toolbarView = getToolbarView(); + int toolbarHeight = toolbarView.getHeight(); + if (toolbarHeight == 0) { + // If the toolbar is not laid out yet and has a fixed height layout parameter, we assume + // that the toolbar will have this height in the future. + ViewGroup.LayoutParams layoutParams = toolbarView.getLayoutParams(); + if (layoutParams != null) { + if (layoutParams.height > 0) { + toolbarHeight = layoutParams.height; + } else { + toolbarView.measure( + MeasureSpec.makeMeasureSpec(mContainerWidth, MeasureSpec.EXACTLY), + MeasureSpec.makeMeasureSpec( + (int) mContainerHeight, MeasureSpec.AT_MOST)); + toolbarHeight = toolbarView.getMeasuredHeight(); + } + } + } + return (toolbarHeight + mToolbarShadowHeight) / (float) mContainerHeight; + } + + private View getToolbarView() { + return mSheetContent != null && mSheetContent.getToolbarView() != null + ? mSheetContent.getToolbarView() + : mDefaultToolbarView; + } + + /** + * @return The ratio of the height of the screen that the half expanded state is. + */ + @VisibleForTesting + float getHalfRatio() { + if (mContainerHeight <= 0 || !isHalfStateEnabled()) return 0; + + float customHalfRatio = mSheetContent.getHalfHeightRatio(); + assert customHalfRatio + != HeightMode.WRAP_CONTENT + : "Half-height cannot be WRAP_CONTENT. This is only supported for full-height."; + + return customHalfRatio == HeightMode.DEFAULT ? HALF_HEIGHT_RATIO : customHalfRatio; + } + + /** + * @return The ratio of the height of the screen that the fully expanded state is. + */ + @VisibleForTesting + float getFullRatio() { + if (mContainerHeight <= 0 || mSheetContent == null) return 0; + + float customFullRatio = mSheetContent.getFullHeightRatio(); + assert customFullRatio != HeightMode.DISABLED : "The full height cannot be DISABLED."; + + if (isFullHeightWrapContent()) { + ensureContentDesiredHeightIsComputed(); + float heightPx = + Math.min(mContainerHeight, mContentDesiredHeight + mToolbarShadowHeight); + return heightPx / mContainerHeight; + } + + return customFullRatio == HeightMode.DEFAULT + ? (mContainerHeight + mToolbarShadowHeight) / (float) mContainerHeight + : customFullRatio; + } + + /** + * @return The height of the container that the bottom sheet exists in. + */ + public float getSheetContainerHeight() { + return mContainerHeight; + } + + /** + * Sends notifications if the sheet is transitioning from the peeking to half expanded state and + * from the peeking to fully expanded state. The peek to half events are only sent when the + * sheet is between the peeking and half states. + */ + private void sendOffsetChangeEvents() { + float offsetWithBrowserControls = getCurrentOffsetPx() - getOffsetFromBrowserControls(); + + // Do not send events for states less than the hidden state unless 0 has not been sent. + if (offsetWithBrowserControls <= getSheetHeightForState(SheetState.HIDDEN) + && mLastOffsetRatioSent <= 0) { + return; + } + + float screenRatio = + mContainerHeight > 0 ? offsetWithBrowserControls / (float) mContainerHeight : 0; + + // This ratio is relative to the peek and full positions of the sheet. + float maxHiddenFullRatio = getFullRatio() - getHiddenRatio(); + float hiddenFullRatio = maxHiddenFullRatio == 0 + ? 0 + : MathUtils.clamp((screenRatio - getHiddenRatio()) / maxHiddenFullRatio, 0, 1); + + if (offsetWithBrowserControls < getSheetHeightForState(SheetState.HIDDEN)) { + mLastOffsetRatioSent = 0; + } else { + mLastOffsetRatioSent = + MathUtils.areFloatsEqual(hiddenFullRatio, 0) ? 0 : hiddenFullRatio; + } + + for (BottomSheetObserver o : mObservers) { + o.onSheetOffsetChanged(mLastOffsetRatioSent, getCurrentOffsetPx()); + } + + if (isPeekStateEnabled() + && MathUtils.areFloatsEqual( + offsetWithBrowserControls, getSheetHeightForState(SheetState.PEEK))) { + for (BottomSheetObserver o : mObservers) o.onSheetFullyPeeked(); + } + } + + /** @see #setSheetState(int, boolean, int) */ + void setSheetState(@SheetState int state, boolean animate) { + setSheetState(state, animate, StateChangeReason.NONE); + } + + /** + * Moves the sheet to the provided state. + * @param state The state to move the panel to. This cannot be SheetState.SCROLLING or + * SheetState.NONE. + * @param animate If true, the sheet will animate to the provided state, otherwise it will + * move there instantly. + * @param reason The reason the sheet state is changing. This can be specified to indicate to + * observers that a more specific event has occurred, otherwise + * STATE_CHANGE_REASON_NONE can be used. + */ + void setSheetState(@SheetState int state, boolean animate, @StateChangeReason int reason) { + assert state != SheetState.NONE; + + // Setting state to SCROLLING is not a valid operation. This can happen only when + // we're already in the scrolling state. Make it no-op. + if (state == SheetState.SCROLLING) { + assert mCurrentState == SheetState.SCROLLING && isRunningSettleAnimation(); + return; + } + + if (state == SheetState.HALF && !isHalfStateEnabled()) state = SheetState.FULL; + + mTargetState = state; + + cancelAnimation(); + + if (animate && state != mCurrentState) { + createSettleAnimation(state, reason); + } else { + setSheetOffsetFromBottom(getSheetHeightForState(state), reason); + setInternalCurrentState(mTargetState, reason); + mTargetState = SheetState.NONE; + } + } + + /** + * @return The target state that the sheet is moving to during animation. If the sheet is + * stationary or a target state has not been determined, SheetState.NONE will be + * returned. + */ + int getTargetSheetState() { + return mTargetState; + } + + /** + * @return The current state of the bottom sheet. If the sheet is animating, this will be the + * state the sheet is animating to. + */ + @SheetState + int getSheetState() { + return mCurrentState; + } + + /** @return Whether the sheet is currently open. */ + boolean isSheetOpen() { + return mIsSheetOpen; + } + + /** + * Set the current state of the bottom sheet. This is for internal use to notify observers of + * state change events. + * @param state The current state of the sheet. + * @param reason The reason the state is changing if any. + */ + private void setInternalCurrentState(@SheetState int state, @StateChangeReason int reason) { + if (state == mCurrentState) return; + + // TODO(mdjones): This shouldn't be able to happen, but does occasionally during layout. + // Fix the race condition that is making this happen. + if (state == SheetState.NONE) { + setSheetState(getTargetSheetState(getCurrentOffsetPx(), 0), false); + return; + } + + // Remember which state precedes the scrolling. + mScrollingStartState = state == SheetState.SCROLLING + ? mCurrentState != SheetState.SCROLLING ? mCurrentState : SheetState.NONE + : SheetState.NONE; // Not scrolling anymore. + mCurrentState = state; + + if (mCurrentState == SheetState.HALF || mCurrentState == SheetState.FULL) { + int resId = mCurrentState == SheetState.FULL + ? getCurrentSheetContent().getSheetFullHeightAccessibilityStringId() + : getCurrentSheetContent().getSheetHalfHeightAccessibilityStringId(); + announceForAccessibility(getResources().getString(resId)); + + // TalkBack will announce the content description if it has changed, so wait to set the + // content description until after announcing full/half height. + setFocusable(true); + setFocusableInTouchMode(true); + String contentDescription = getResources().getString( + getCurrentSheetContent().getSheetContentDescriptionStringId()); + + if (getCurrentSheetContent().swipeToDismissEnabled()) { + contentDescription += ". " + + getResources().getString( + org.chromium.components.browser_ui.widget.R.string + .bottom_sheet_accessibility_description); + } + + setContentDescription(contentDescription); + if (getFocusedChild() == null) requestFocus(); + } + + for (BottomSheetObserver o : mObservers) { + o.onSheetStateChanged(mCurrentState); + } + } + + /** + * If the animation to settle the sheet in one of its states is running. + * @return True if the animation is running. + */ + private boolean isRunningSettleAnimation() { + return mSettleAnimator != null; + } + + /** @return The current sheet content, or null if there is no content. */ + @Nullable + BottomSheetContent getCurrentSheetContent() { + return mSheetContent; + } + + /** + * Gets the height of the bottom sheet based on a provided state. + * @param state The state to get the height from. + * @return The height of the sheet at the provided state. + */ + private float getSheetHeightForState(@SheetState int state) { + if (isFullHeightWrapContent() && state == SheetState.FULL) { + ensureContentDesiredHeightIsComputed(); + return mContentDesiredHeight + mToolbarShadowHeight; + } + + return getRatioForState(state) * mContainerHeight; + } + + private void ensureContentDesiredHeightIsComputed() { + if (mContentDesiredHeight != HEIGHT_UNSPECIFIED) { + return; + } + + mSheetContent.getContentView().measure( + MeasureSpec.makeMeasureSpec(mContainerWidth, MeasureSpec.EXACTLY), + MeasureSpec.makeMeasureSpec(mContainerHeight, MeasureSpec.AT_MOST)); + mContentDesiredHeight = mSheetContent.getContentView().getMeasuredHeight(); + } + + private float getRatioForState(int state) { + switch (state) { + case SheetState.HIDDEN: + return getHiddenRatio(); + case SheetState.PEEK: + return getPeekRatio(); + case SheetState.HALF: + return getHalfRatio(); + case SheetState.FULL: + return getFullRatio(); + } + + throw new IllegalArgumentException("Invalid state: " + state); + } + + /** + * Adds an observer to the bottom sheet. + * @param observer The observer to add. + */ + void addObserver(BottomSheetObserver observer) { + mObservers.addObserver(observer); + } + + /** + * Removes an observer to the bottom sheet. + * @param observer The observer to remove. + */ + void removeObserver(BottomSheetObserver observer) { + mObservers.removeObserver(observer); + } + + /** + * Gets the target state of the sheet based on the sheet's height and velocity. + * @param sheetHeight The current height of the sheet. + * @param yVelocity The current Y velocity of the sheet. If this value is positive, the movement + * is from bottom to top. + * @return The target state of the bottom sheet. + */ + @SheetState + private int getTargetSheetState(float sheetHeight, float yVelocity) { + if (sheetHeight <= getMinOffsetPx()) return getMinSwipableSheetState(); + if (sheetHeight >= getMaxOffsetPx()) return SheetState.FULL; + + boolean isMovingDownward = yVelocity < 0; + + // If velocity shouldn't affect dismissing the sheet, reverse effect on the sheet height. + if (isMovingDownward && !swipeToDismissEnabled()) sheetHeight -= yVelocity; + + // Find the two states that the sheet height is between. + @SheetState + int prevState = mScrollingStartState; + @SheetState + int nextState = isMovingDownward ? getLargestCollapsingState(isMovingDownward, sheetHeight) + : getSmallestExpandingState(isMovingDownward, sheetHeight); + + // Go into the next state only if the threshold for minimal change has been cleared. + return hasCrossedThresholdToNextState(prevState, nextState, sheetHeight, isMovingDownward) + ? nextState + : prevState; + } + + /** + * Returns whether the sheet was scrolled far enough to transition into the next state. + * @param prev The state before the scrolling transition happened. + * @param next The state before the scrolling transitions into. + * @param sheetMovesDown True if the sheet moves down. + * @param sheetHeight The current sheet height in flux. + * @return True, iff the sheet was scrolled far enough to transition from |prev| to |next|. + */ + private boolean hasCrossedThresholdToNextState( + @SheetState int prev, @SheetState int next, float sheetHeight, boolean sheetMovesDown) { + if (next == prev) return false; + // Moving from an internal/temporary state always works: + if (prev == SheetState.NONE || prev == SheetState.SCROLLING) return true; + float lowerBound = getSheetHeightForState(prev); + float distance = getSheetHeightForState(next) - lowerBound; + return Math.abs((sheetHeight - lowerBound) / distance) + > getThresholdToNextState(prev, next, sheetMovesDown); + } + + /** + * The threshold to enter a state depends on whether a transition skips the half state. The more + * states to cross, the smaller the (percentual) threshold. A small threshold is used iff: + * * It doesn't move into the HALF state, + * * Skipping the HALF state is allowed, and + * * The is large enough to skip the HALF state + * @param prev The state before the scrolling transition happened. + * @param next The state before the scrolling transitions into. + * @param sheetMovesDown True if the sheet is being moved down. + * @return a threshold (as percentage of the scroll distance covered). + */ + private float getThresholdToNextState( + @SheetState int prev, @SheetState int next, boolean sheetMovesDown) { + if (next == SheetState.HALF) return THRESHOLD_TO_NEXT_STATE_3; + boolean crossesHalf = sheetMovesDown && prev > SheetState.HALF && next < SheetState.HALF + || !sheetMovesDown && prev < SheetState.HALF && next > SheetState.HALF; + if (!crossesHalf) return THRESHOLD_TO_NEXT_STATE_3; + if (!shouldSkipHalfStateOnScrollingDown()) return THRESHOLD_TO_NEXT_STATE_3; + return THRESHOLD_TO_NEXT_STATE_2; + } + + /** + * Returns the largest, acceptable state whose height is smaller than the given sheet height. + * E.g. if a sheet is between FULL and HALF, collapsing states are PEEK and HALF. Although HALF + * is closer to the sheet's height, it might have to be skipped. Then, PEEK is returned instead. + * @param sheetMovesDown If the sheet moves down, some smaller states might be skipped. + * @param sheetHeight The current sheet height in flux. + * @return The largest, acceptable, collapsing state. + */ + private @SheetState int getLargestCollapsingState(boolean sheetMovesDown, float sheetHeight) { + @SheetState + int largestCollapsingState = getMinSwipableSheetState(); + boolean skipHalfState = !isHalfStateEnabled() || shouldSkipHalfStateOnScrollingDown(); + for (@SheetState int i = largestCollapsingState + 1; i < SheetState.FULL; i++) { + if (i == SheetState.PEEK && !isPeekStateEnabled()) continue; + if (i == SheetState.HALF && skipHalfState) continue; + + if (sheetHeight > getSheetHeightForState(i) + || sheetHeight == getSheetHeightForState(i) && !sheetMovesDown) { + largestCollapsingState = i; + } + } + return largestCollapsingState; + } + + /** + * Returns the smallest, acceptable state whose height is larger than the given sheet height. + * E.g. if the sheet is between PEEK and HALF, expanding states are HALF and FULL. Although HALF + * is closer to the sheet's height, it might not be enabled. Then, FULL is returned instead. + * @param sheetMovesDown If the sheet moves down, some collapsing states might be skipped. This + * affects the smallest possible expanding state as well. + * @param sheetHeight The current sheet height in flux. + * @return The smallest, acceptable, expanding state. + */ + private @SheetState int getSmallestExpandingState(boolean sheetMovesDown, float sheetHeight) { + @SheetState + int largestCollapsingState = getLargestCollapsingState(sheetMovesDown, sheetHeight); + @SheetState + int smallestExpandingState = SheetState.FULL; + for (@SheetState int i = smallestExpandingState - 1; i > largestCollapsingState + 1; i--) { + if (i == SheetState.HALF && !isHalfStateEnabled()) continue; + if (i == SheetState.PEEK && !isPeekStateEnabled()) continue; + + if (sheetHeight <= getSheetHeightForState(i)) { + smallestExpandingState = i; + } + } + + return smallestExpandingState; + } + + @VisibleForTesting + public static void setSmallScreenForTesting(boolean isSmallScreen) { + sIsSmallScreenForTesting = isSmallScreen; + } + + public boolean isSmallScreen() { + if (sIsSmallScreenForTesting != null) return sIsSmallScreenForTesting; + + // A small screen is defined by there being less than 160dp between half and full states. + float fullHeightRatio = + (mContainerHeight + mToolbarShadowHeight) / (float) mContainerHeight; + float fullToHalfDiff = (fullHeightRatio - HALF_HEIGHT_RATIO) * mContainerHeight; + return fullToHalfDiff < mMinHalfFullDistance; + } + + /** + * @return The height of the toolbar shadow. + */ + public int getToolbarShadowHeight() { + return mToolbarShadowHeight; + } + + /** + * Called when the sheet content has changed, to update dependent state and notify observers. + * @param content The new sheet content, or null if the sheet has no content. + */ + protected void onSheetContentChanged(@Nullable final BottomSheetContent content) { + mSheetContent = content; + + if (isFullHeightWrapContent()) { + // Listen for layout/size changes. + if (!content.setContentSizeListener(this::onContentSizeChanged)) { + content.getContentView().addOnLayoutChangeListener(this); + } + + invalidateContentDesiredHeight(); + ensureContentIsWrapped(/* animate= */ true); + + // HALF state is forbidden when wrapping the content. + if (mCurrentState == SheetState.HALF) { + setSheetState(SheetState.FULL, /* animate= */ true); + } + } + + for (BottomSheetObserver o : mObservers) { + o.onSheetContentChanged(content); + } + mToolbarHolder.setBackgroundColor(Color.TRANSPARENT); + } + + /** + * Called when the sheet content layout changed. + */ + @Override + public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, + int oldTop, int oldRight, int oldBottom) { + invalidateContentDesiredHeight(); + ensureContentIsWrapped(/* animate= */ true); + } + + /** + * Called when the sheet content size changed. + */ + private void onContentSizeChanged(int width, int height, int oldWidth, int oldHeight) { + boolean heightChanged = mContentDesiredHeight != height; + mContentDesiredHeight = height; + + if (heightChanged && mCurrentState == SheetState.SCROLLING) { + endAnimations(); + return; + } + + ensureContentIsWrapped(/* animate= */ false); + } + + private void ensureContentIsWrapped(boolean animate) { + if (mCurrentState == SheetState.HIDDEN || mCurrentState == SheetState.PEEK) return; + + // The SCROLLING state is used when animating the sheet height or when the user is swiping + // the sheet. If it is the latter, we should not change the sheet height. + if (!isRunningSettleAnimation() && mCurrentState == SheetState.SCROLLING) return; + setSheetState(mCurrentState, animate); + } + + private void invalidateContentDesiredHeight() { + mContentDesiredHeight = HEIGHT_UNSPECIFIED; + } + + /** + * WARNING: This destroys the state of the BottomSheet. Only use in tests and only use once. + * Puts the sheet into a scrolling state that can't be reached in tests otherwise. + * + * @param sheetHeightInPx The height in px that the sheet should be "scrolled" to. + * @param yUpwardsVelocity The sheet's upwards y velocity when reaching the scrolled height. + * @return The state the bottom sheet would target when the scrolling ends. + */ + @VisibleForTesting + @SheetState + int forceScrollingStateForTesting(float sheetHeightInPx, float yUpwardsVelocity) { + mScrollingStartState = mCurrentState; + mCurrentState = SheetState.SCROLLING; + return getTargetSheetState(sheetHeightInPx, yUpwardsVelocity); + } +} diff --git a/chromium/components/browser_ui/android/bottomsheet/internal/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetControllerFactory.java b/chromium/components/browser_ui/android/bottomsheet/internal/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetControllerFactory.java new file mode 100644 index 00000000000..732588d5234 --- /dev/null +++ b/chromium/components/browser_ui/android/bottomsheet/internal/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetControllerFactory.java @@ -0,0 +1,33 @@ +// Copyright 2020 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.components.browser_ui.bottomsheet; + +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; + +import org.chromium.base.Callback; +import org.chromium.base.supplier.Supplier; +import org.chromium.components.browser_ui.widget.scrim.ScrimCoordinator; +import org.chromium.ui.KeyboardVisibilityDelegate; + +/** A factory for producing a {@link BottomSheetController}. */ +public class BottomSheetControllerFactory { + /** + * @param scrim A supplier of scrim to be shown behind the sheet. + * @param initializedCallback A callback for the sheet having been created. + * @param window The activity's window. + * @param keyboardDelegate A means of hiding the keyboard. + * @param root The view that should contain the sheet. + * @param inflater A mechanism for building views from XML. + * @return A new instance of the {@link BottomSheetController}. + */ + public static ManagedBottomSheetController createBottomSheetController( + final Supplier<ScrimCoordinator> scrim, Callback<View> initializedCallback, + Window window, KeyboardVisibilityDelegate keyboardDelegate, Supplier<ViewGroup> root) { + return new BottomSheetControllerImpl( + scrim, initializedCallback, window, keyboardDelegate, root); + } +} diff --git a/chromium/components/browser_ui/android/bottomsheet/internal/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetControllerImpl.java b/chromium/components/browser_ui/android/bottomsheet/internal/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetControllerImpl.java new file mode 100644 index 00000000000..88dd095af89 --- /dev/null +++ b/chromium/components/browser_ui/android/bottomsheet/internal/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetControllerImpl.java @@ -0,0 +1,505 @@ +// Copyright 2018 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.components.browser_ui.bottomsheet; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; + +import androidx.annotation.VisibleForTesting; + +import org.chromium.base.Callback; +import org.chromium.base.supplier.Supplier; +import org.chromium.components.browser_ui.widget.scrim.ScrimCoordinator; +import org.chromium.components.browser_ui.widget.scrim.ScrimProperties; +import org.chromium.ui.KeyboardVisibilityDelegate; +import org.chromium.ui.modelutil.PropertyModel; +import org.chromium.ui.util.AccessibilityUtil; +import org.chromium.ui.util.TokenHolder; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.PriorityQueue; + +/** + * This class is responsible for managing the content shown by the {@link BottomSheet}. Features + * wishing to show content in the {@link BottomSheet} UI must implement {@link BottomSheetContent} + * and call {@link #requestShowContent(BottomSheetContent, boolean)} which will return true if the + * content was actually shown (see full doc on method). + */ +class BottomSheetControllerImpl implements ManagedBottomSheetController { + /** The initial capacity for the priority queue handling pending content show requests. */ + private static final int INITIAL_QUEUE_CAPACITY = 1; + + /** The height of the shadow that sits above the toolbar. */ + private int mToolbarShadowHeight; + + /** The offset of the toolbar shadow from the top that remains empty. */ + private int mShadowTopOffset; + + /** A handle to the {@link BottomSheet} that this class controls. */ + private BottomSheet mBottomSheet; + + /** A queue for content that is waiting to be shown in the {@link BottomSheet}. */ + private PriorityQueue<BottomSheetContent> mContentQueue; + + /** Whether the controller is already processing a hide request for the tab. */ + private boolean mIsProcessingHideRequest; + + /** A runnable that initializes the bottom sheet when necessary. */ + private Runnable mSheetInitializer; + + /** + * A list of observers maintained by this controller until the bottom sheet is created, at which + * point they will be added to the bottom sheet. + */ + private List<BottomSheetObserver> mPendingSheetObservers; + + /** The state of the sheet so it can be returned to what it was prior to suppression. */ + @SheetState + private int mSheetStateBeforeSuppress; + + /** The content being shown prior to the sheet being suppressed. */ + private BottomSheetContent mContentWhenSuppressed; + + /** A means of accessing the ScrimCoordinator. */ + private Supplier<ScrimCoordinator> mScrimCoordinatorSupplier; + + /** + * A set of tokens for features suppressing the bottom sheet. If this holder has tokens, the + * sheet is suppressed. + */ + private final TokenHolder mSuppressionTokens; + + /** A means of checking whether accessibility is currently enabled. */ + private AccessibilityUtil mAccessibilityUtil; + + /** + * Build a new controller of the bottom sheet. + * @param scrim A supplier of the scrim that shows when the bottom sheet is opened. + * @param initializedCallback A callback for the sheet being created (as the sheet is not + * initialized until first use. + * @param window A means of accessing the screen size. + * @param keyboardDelegate A means of hiding the keyboard. + * @param root The view that should contain the sheet. + */ + public BottomSheetControllerImpl(final Supplier<ScrimCoordinator> scrim, + Callback<View> initializedCallback, Window window, + KeyboardVisibilityDelegate keyboardDelegate, Supplier<ViewGroup> root) { + mScrimCoordinatorSupplier = scrim; + mPendingSheetObservers = new ArrayList<>(); + mSuppressionTokens = new TokenHolder(() -> onSuppressionTokensChanged()); + + mSheetInitializer = () -> { + initializeSheet(initializedCallback, window, keyboardDelegate, root); + }; + } + + /** + * Do the actual initialization of the bottom sheet. + * @param initializedCallback A callback for the creation of the sheet. + * @param window A means of accessing the screen size. + * @param keyboardDelegate A means of hiding the keyboard. + * @param root The view that should contain the sheet. + */ + private void initializeSheet(Callback<View> initializedCallback, Window window, + KeyboardVisibilityDelegate keyboardDelegate, Supplier<ViewGroup> root) { + LayoutInflater.from(root.get().getContext()).inflate(R.layout.bottom_sheet, root.get()); + mBottomSheet = (BottomSheet) root.get().findViewById(R.id.bottom_sheet); + initializedCallback.onResult(mBottomSheet); + + mBottomSheet.init(window, keyboardDelegate); + mBottomSheet.setAccssibilityUtil(mAccessibilityUtil); + mToolbarShadowHeight = mBottomSheet.getResources().getDimensionPixelOffset( + BottomSheet.getTopShadowResourceId()); + mShadowTopOffset = mBottomSheet.getResources().getDimensionPixelOffset( + BottomSheet.getShadowTopOffsetResourceId()); + + // Initialize the queue with a comparator that checks content priority. + mContentQueue = new PriorityQueue<>(INITIAL_QUEUE_CAPACITY, + (content1, content2) -> content1.getPriority() - content2.getPriority()); + + PropertyModel scrimProperties = + new PropertyModel.Builder(ScrimProperties.REQUIRED_KEYS) + .with(ScrimProperties.TOP_MARGIN, 0) + .with(ScrimProperties.AFFECTS_STATUS_BAR, true) + .with(ScrimProperties.ANCHOR_VIEW, mBottomSheet) + .with(ScrimProperties.SHOW_IN_FRONT_OF_ANCHOR_VIEW, false) + .with(ScrimProperties.CLICK_DELEGATE, + () -> { + if (!mBottomSheet.isSheetOpen()) return; + mBottomSheet.setSheetState( + mBottomSheet.getMinSwipableSheetState(), true, + StateChangeReason.TAP_SCRIM); + }) + .build(); + + mBottomSheet.addObserver(new EmptyBottomSheetObserver() { + /** + * Whether the scrim was shown for the last content. + * TODO(mdjones): We should try to make sure the content in the sheet is not nulled + * prior to the close event occurring; sheets that don't have a peek + * state make this difficult since the sheet needs to be hidden before it + * is closed. + */ + private boolean mScrimShown; + + @Override + public void onSheetOpened(@StateChangeReason int reason) { + if (mBottomSheet.getCurrentSheetContent() != null + && mBottomSheet.getCurrentSheetContent().hasCustomScrimLifecycle()) { + return; + } + + mScrimCoordinatorSupplier.get().showScrim(scrimProperties); + mScrimShown = true; + } + + @Override + public void onSheetClosed(@StateChangeReason int reason) { + // Hide the scrim if the current content doesn't have a custom scrim lifecycle. + if (mScrimShown) { + mScrimCoordinatorSupplier.get().hideScrim(true); + mScrimShown = false; + } + + // Try to swap contents unless the sheet's content has a custom lifecycle. + if (mBottomSheet.getCurrentSheetContent() != null + && !mBottomSheet.getCurrentSheetContent().hasCustomLifecycle()) { + // If the sheet is closed, it is an opportunity for another content to try to + // take its place if it is a higher priority. + BottomSheetContent content = mBottomSheet.getCurrentSheetContent(); + BottomSheetContent nextContent = mContentQueue.peek(); + if (content != null && nextContent != null + && nextContent.getPriority() < content.getPriority()) { + mContentQueue.add(content); + mBottomSheet.setSheetState(SheetState.HIDDEN, true); + } + } + } + + @Override + public void onSheetStateChanged(@SheetState int state) { + // If hiding request is in progress, destroy the current sheet content being hidden + // even when it is in suppressed state. See https://crbug.com/1057966. + if (state != SheetState.HIDDEN + || (!mIsProcessingHideRequest && mSuppressionTokens.hasTokens())) { + return; + } + if (mBottomSheet.getCurrentSheetContent() != null) { + mBottomSheet.getCurrentSheetContent().destroy(); + } + mIsProcessingHideRequest = false; + showNextContent(true); + } + }); + + // Add any of the pending observers that were added prior to the sheet being created. + for (int i = 0; i < mPendingSheetObservers.size(); i++) { + mBottomSheet.addObserver(mPendingSheetObservers.get(i)); + } + mPendingSheetObservers.clear(); + + mSheetInitializer = null; + } + + @Override + public void setBrowserControlsHiddenRatio(float ratio) { + if (mBottomSheet != null) mBottomSheet.setBrowserControlsHiddenRatio(ratio); + } + + @Override + public ScrimCoordinator getScrimCoordinator() { + return mScrimCoordinatorSupplier.get(); + } + + @Override + public PropertyModel createScrimParams() { + return new PropertyModel.Builder(ScrimProperties.REQUIRED_KEYS) + .with(ScrimProperties.TOP_MARGIN, 0) + .with(ScrimProperties.AFFECTS_STATUS_BAR, true) + .with(ScrimProperties.ANCHOR_VIEW, mBottomSheet) + .with(ScrimProperties.SHOW_IN_FRONT_OF_ANCHOR_VIEW, false) + .with(ScrimProperties.CLICK_DELEGATE, + () -> { + if (!mBottomSheet.isSheetOpen()) return; + mBottomSheet.setSheetState(mBottomSheet.getMinSwipableSheetState(), + true, StateChangeReason.TAP_SCRIM); + }) + .build(); + } + + // Destroyable implementation. + @Override + public void destroy() { + if (mBottomSheet != null) mBottomSheet.destroy(); + } + + @Override + public boolean handleBackPress() { + // If suppressed (therefore invisible), users are likely to expect for Chrome + // browser, not the bottom sheet, to react. Do not consume the event. + if (mBottomSheet == null || mSuppressionTokens.hasTokens()) return false; + + // Give the sheet the opportunity to handle the back press itself before falling to the + // default "close" behavior. + if (getCurrentSheetContent() != null && getCurrentSheetContent().handleBackPress()) { + return true; + } + + if (!mBottomSheet.isSheetOpen()) return false; + int sheetState = mBottomSheet.getMinSwipableSheetState(); + mBottomSheet.setSheetState(sheetState, true, StateChangeReason.BACK_PRESS); + return true; + } + + @Override + public BottomSheetContent getCurrentSheetContent() { + return mBottomSheet == null ? null : mBottomSheet.getCurrentSheetContent(); + } + + @Override + @SheetState + public int getSheetState() { + return mBottomSheet == null ? SheetState.HIDDEN : mBottomSheet.getSheetState(); + } + + @Override + @SheetState + public int getTargetSheetState() { + return mBottomSheet == null ? SheetState.NONE : mBottomSheet.getTargetSheetState(); + } + + @Override + public boolean isSheetOpen() { + return mBottomSheet != null && mBottomSheet.isSheetOpen(); + } + + @Override + public boolean isSheetHiding() { + return mBottomSheet == null ? false : mBottomSheet.isHiding(); + } + + @Override + public int getCurrentOffset() { + return mBottomSheet == null ? 0 : (int) mBottomSheet.getCurrentOffsetPx(); + } + + @Override + public int getContainerHeight() { + return mBottomSheet != null ? (int) mBottomSheet.getSheetContainerHeight() : 0; + } + + @Override + public int getTopShadowHeight() { + return mToolbarShadowHeight + mShadowTopOffset; + } + + @Override + public void addObserver(BottomSheetObserver observer) { + if (mBottomSheet == null) { + mPendingSheetObservers.add(observer); + return; + } + mBottomSheet.addObserver(observer); + } + + @Override + public void removeObserver(BottomSheetObserver observer) { + if (mBottomSheet != null) { + mBottomSheet.removeObserver(observer); + } else { + mPendingSheetObservers.remove(observer); + } + } + + /** Handle a change in the state of the token holder responsible for the suppression tokens. */ + private void onSuppressionTokensChanged() { + if (!mSuppressionTokens.hasTokens()) doUnsuppression(); + } + + @Override + public int suppressSheet(@StateChangeReason int reason) { + boolean hadTokens = mSuppressionTokens.hasTokens(); + int token = mSuppressionTokens.acquireToken(); + if (!hadTokens && mBottomSheet != null) { + mSheetStateBeforeSuppress = getSheetState(); + mContentWhenSuppressed = getCurrentSheetContent(); + mBottomSheet.setSheetState(SheetState.HIDDEN, false, reason); + } + + return token; + } + + @Override + public void unsuppressSheet(int token) { + mSuppressionTokens.releaseToken(token); + } + + private void doUnsuppression() { + if (mBottomSheet == null) return; + + if (mBottomSheet.getCurrentSheetContent() != null) { + @SheetState + int openState = mContentWhenSuppressed == getCurrentSheetContent() + ? mSheetStateBeforeSuppress + : mBottomSheet.getOpeningState(); + mBottomSheet.setSheetState(openState, true); + } else { + // In the event the previous content was hidden, try to show the next one. + showNextContent(true); + } + mContentWhenSuppressed = null; + mSheetStateBeforeSuppress = SheetState.NONE; + } + + @Override + public void setAccssibilityUtil(AccessibilityUtil enabledSupplier) { + mAccessibilityUtil = enabledSupplier; + } + + @VisibleForTesting + void setSheetStateForTesting(@SheetState int state, boolean animate) { + mBottomSheet.setSheetState(state, animate); + } + + @VisibleForTesting + View getBottomSheetViewForTesting() { + return mBottomSheet; + } + + @VisibleForTesting + public void endAnimationsForTesting() { + mBottomSheet.endAnimations(); + } + + @Override + public boolean requestShowContent(BottomSheetContent content, boolean animate) { + if (mBottomSheet == null) mSheetInitializer.run(); + + // If already showing the requested content, do nothing. + if (content == mBottomSheet.getCurrentSheetContent()) return true; + + boolean shouldSuppressExistingContent = mBottomSheet.getCurrentSheetContent() != null + && content.getPriority() < mBottomSheet.getCurrentSheetContent().getPriority() + && canBottomSheetSwitchContent(); + + // Always add the content to the queue, it will be handled after the sheet closes if + // necessary. If already hidden, |showNextContent| will handle the request. + mContentQueue.add(content); + + if (mBottomSheet.getCurrentSheetContent() == null) { + showNextContent(animate); + return true; + } else if (shouldSuppressExistingContent) { + mContentQueue.add(mBottomSheet.getCurrentSheetContent()); + mBottomSheet.setSheetState(SheetState.HIDDEN, animate); + return true; + } + return false; + } + + @Override + public void hideContent( + BottomSheetContent content, boolean animate, @StateChangeReason int hideReason) { + if (mBottomSheet == null) return; + + if (content != mBottomSheet.getCurrentSheetContent()) { + mContentQueue.remove(content); + return; + } + + if (mIsProcessingHideRequest) return; + + // Handle showing the next content if it exists. + if (mBottomSheet.getSheetState() == SheetState.HIDDEN) { + // If the sheet is already hidden, destroy it and simply show the next content. + // TODO(mdjones): Add tests to make sure the content is being destroyed as expected. + if (mBottomSheet.getCurrentSheetContent() != null) { + mBottomSheet.getCurrentSheetContent().destroy(); + } + showNextContent(animate); + } else { + mIsProcessingHideRequest = true; + mBottomSheet.setSheetState(SheetState.HIDDEN, animate, hideReason); + } + } + + @Override + public void hideContent(BottomSheetContent content, boolean animate) { + hideContent(content, animate, StateChangeReason.NONE); + } + + @Override + public void expandSheet() { + if (mBottomSheet == null || mSuppressionTokens.hasTokens()) return; + + if (mBottomSheet.getCurrentSheetContent() == null) return; + mBottomSheet.setSheetState(SheetState.HALF, true); + } + + @Override + public boolean collapseSheet(boolean animate) { + if (mBottomSheet == null || mSuppressionTokens.hasTokens()) return false; + if (mBottomSheet.isSheetOpen() && mBottomSheet.isPeekStateEnabled()) { + mBottomSheet.setSheetState(SheetState.PEEK, animate); + return true; + } + return false; + } + + /** + * Show the next {@link BottomSheetContent} if it is available and peek the sheet. If no content + * is available the sheet's content is set to null. + * @param animate Whether the sheet should animate opened. + */ + private void showNextContent(boolean animate) { + if (mContentQueue.isEmpty()) { + mBottomSheet.showContent(null); + return; + } + + BottomSheetContent nextContent = mContentQueue.poll(); + mBottomSheet.showContent(nextContent); + mBottomSheet.setSheetState(mBottomSheet.getOpeningState(), animate); + } + + @Override + public void clearRequestsAndHide() { + if (mBottomSheet == null) return; + + clearRequests(mContentQueue.iterator()); + + BottomSheetContent currentContent = mBottomSheet.getCurrentSheetContent(); + if (currentContent == null || !currentContent.hasCustomLifecycle()) { + hideContent(currentContent, /* animate= */ true); + } + mContentWhenSuppressed = null; + mSheetStateBeforeSuppress = SheetState.NONE; + } + + /** + * Remove all contents from {@code iterator} that don't have a custom lifecycle. + * @param iterator The iterator whose items must be removed. + */ + private void clearRequests(Iterator<BottomSheetContent> iterator) { + while (iterator.hasNext()) { + if (!iterator.next().hasCustomLifecycle()) { + iterator.remove(); + } + } + } + + /** + * The bottom sheet cannot change content while it is open. If the user has the bottom sheet + * open, they are currently engaged in a task and shouldn't be interrupted. + * @return Whether the sheet currently supports switching its content. + */ + private boolean canBottomSheetSwitchContent() { + return !mBottomSheet.isSheetOpen(); + } +} diff --git a/chromium/components/browser_ui/android/bottomsheet/internal/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetSwipeDetector.java b/chromium/components/browser_ui/android/bottomsheet/internal/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetSwipeDetector.java new file mode 100644 index 00000000000..ae9d4e7e04d --- /dev/null +++ b/chromium/components/browser_ui/android/bottomsheet/internal/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetSwipeDetector.java @@ -0,0 +1,269 @@ +// Copyright 2017 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.components.browser_ui.bottomsheet; + +import android.content.Context; +import android.view.GestureDetector; +import android.view.MotionEvent; +import android.view.VelocityTracker; + +import org.chromium.base.MathUtils; +import org.chromium.base.ThreadUtils; + +/** + * A class that determines whether a sequence of motion events is a valid swipe in the context of a + * bottom sheet. The {@link SwipeableBottomSheet} that this class is built with provides information + * useful to determining if a swipe is valid. This class does not move the sheet itself, it only + * provides information on if/where it should move and whether it should animate. The + * {@link SwipeableBottomSheet} is responsible for applying the changes to the relevant views. Each + * swipe or fling is converted into a sequence of calls to + * {@link SwipeableBottomSheet#setSheetOffset(float, boolean)}. + */ +class BottomSheetSwipeDetector extends GestureDetector.SimpleOnGestureListener { + /** The minimum y/x ratio that a scroll must have to be considered vertical. */ + private static final float MIN_VERTICAL_SCROLL_SLOPE = 2.0f; + + /** + * The base duration of the settling animation of the sheet. 218 ms is a spec for material + * design (this is the minimum time a user is guaranteed to pay attention to something). + */ + public static final long BASE_ANIMATION_DURATION_MS = 218; + + /** For detecting scroll and fling events on the bottom sheet. */ + private final GestureDetector mGestureDetector; + + /** An interface for retrieving information from a bottom sheet. */ + private final SwipeableBottomSheet mSheetDelegate; + + /** Track the velocity of the user's scrolls to determine up or down direction. */ + private VelocityTracker mVelocityTracker; + + /** Whether or not the user is scrolling the bottom sheet. */ + private boolean mIsScrolling; + + /** + * An interface for views that are swipable from the bottom of the screen. This interface + * assumes that any part of the bottom sheet visible at the peeking state is the toolbar. + */ + public interface SwipeableBottomSheet { + /** + * @return Whether the content being shown in the sheet is scrolled to the top. + */ + boolean isContentScrolledToTop(); + + /** + * Gets the sheet's offset from the bottom of the screen. + * @return The sheet's distance from the bottom of the screen. + */ + float getCurrentOffsetPx(); + + /** + * Gets the minimum offset of the bottom sheet. + * @return The min offset. + */ + float getMinOffsetPx(); + + /** + * Gets the maximum offset of the bottom sheet. + * @return The max offset. + */ + float getMaxOffsetPx(); + + /** + * @param event The motion event to test. + * @return Whether the provided motion event is inside the toolbar. + */ + boolean isTouchEventInToolbar(MotionEvent event); + + /** + * Check if a particular gesture or touch event should move the bottom sheet when in peeking + * mode. If the "chrome-home-swipe-logic" flag is not set this function returns true. + * @param initialDownEvent The event that started the scroll. + * @param currentEvent The current motion event. + * @return True if the bottom sheet should move. + */ + boolean shouldGestureMoveSheet(MotionEvent initialDownEvent, MotionEvent currentEvent); + + /** + * Set the sheet's offset. + * @param offset The target offset. + * @param shouldAnimate Whether the sheet should animate to that position. + */ + void setSheetOffset(float offset, boolean shouldAnimate); + } + + /** + * This class is responsible for detecting swipe and scroll events on the bottom sheet or + * ignoring them when appropriate. + */ + private class SwipeGestureListener extends GestureDetector.SimpleOnGestureListener { + @Override + public boolean onDown(MotionEvent e) { + if (e == null) return false; + return mSheetDelegate.shouldGestureMoveSheet(e, e); + } + + @Override + public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { + if (e1 == null || !mSheetDelegate.shouldGestureMoveSheet(e1, e2)) return false; + + // Only start scrolling if the scroll is up or down. If the user is already scrolling, + // continue moving the sheet. + float slope = Math.abs(distanceX) > 0f ? Math.abs(distanceY) / Math.abs(distanceX) + : MIN_VERTICAL_SCROLL_SLOPE; + if (!mIsScrolling && slope < MIN_VERTICAL_SCROLL_SLOPE) { + mVelocityTracker.clear(); + return false; + } + + mVelocityTracker.addMovement(e2); + + boolean isSheetInMaxPosition = MathUtils.areFloatsEqual( + mSheetDelegate.getCurrentOffsetPx(), mSheetDelegate.getMaxOffsetPx()); + + // Allow the bottom sheet's content to be scrolled up without dragging the sheet down. + if (!mSheetDelegate.isTouchEventInToolbar(e2) && isSheetInMaxPosition + && !mSheetDelegate.isContentScrolledToTop()) { + return false; + } + + // If the sheet is in the max position, don't move the sheet if the scroll is upward. + // Instead, allow the sheet's content to handle it if it needs to. + if (isSheetInMaxPosition && distanceY > 0) return false; + + boolean isSheetInMinPosition = MathUtils.areFloatsEqual( + mSheetDelegate.getCurrentOffsetPx(), mSheetDelegate.getMinOffsetPx()); + + // Similarly, if the sheet is in the min position, don't move if the scroll is downward. + if (isSheetInMinPosition && distanceY < 0) return false; + + float newOffset = mSheetDelegate.getCurrentOffsetPx() + distanceY; + + mIsScrolling = true; + + mSheetDelegate.setSheetOffset( + MathUtils.clamp(newOffset, mSheetDelegate.getMinOffsetPx(), + mSheetDelegate.getMaxOffsetPx()), + false); + + return true; + } + + @Override + public void onLongPress(MotionEvent e) { + mIsScrolling = false; + } + + @Override + public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { + if (e1 == null || !mSheetDelegate.shouldGestureMoveSheet(e1, e2) || !mIsScrolling) { + return false; + } + + mIsScrolling = false; + + float newOffset = mSheetDelegate.getCurrentOffsetPx() + getFlingDistance(-velocityY); + + mSheetDelegate.setSheetOffset( + MathUtils.clamp(newOffset, mSheetDelegate.getMinOffsetPx(), + mSheetDelegate.getMaxOffsetPx()), + true); + + return true; + } + } + + /** + * Default constructor. + * @param context A context for the GestureDetector this class uses. + * @param delegate A SwipeableBottomSheet that processes swipes. + */ + public BottomSheetSwipeDetector(Context context, SwipeableBottomSheet delegate) { + mGestureDetector = new GestureDetector( + context, new SwipeGestureListener(), ThreadUtils.getUiThreadHandler()); + mGestureDetector.setIsLongpressEnabled(true); + + mSheetDelegate = delegate; + mVelocityTracker = VelocityTracker.obtain(); + } + + /** + * Test whether or not a motion event should be intercepted by this class. + * @param e The motion event to test. + * @return Whether or not the event was intercepted. + */ + public boolean onInterceptTouchEvent(MotionEvent e) { + // The incoming motion event may have been adjusted by the view sending it down. Create a + // motion event with the raw (x, y) coordinates of the original so the gesture detector + // functions properly. + mGestureDetector.onTouchEvent(createRawMotionEvent(e)); + + return mIsScrolling; + } + + /** + * Process a motion event. + * @param e The motion event to process. + * @return Whether or not the motion event was used. + */ + public boolean onTouchEvent(MotionEvent e) { + // The down event is interpreted above in onInterceptTouchEvent, it does not need to be + // interpreted a second time. + if (e.getActionMasked() != MotionEvent.ACTION_DOWN) { + mGestureDetector.onTouchEvent(createRawMotionEvent(e)); + } + + // If the user is scrolling and the event is a cancel or up action, update scroll state and + // return. Fling should have already cleared the mIsScrolling flag, the following is for the + // non-fling release. + if (mIsScrolling + && (e.getActionMasked() == MotionEvent.ACTION_UP + || e.getActionMasked() == MotionEvent.ACTION_CANCEL)) { + mIsScrolling = false; + + mVelocityTracker.computeCurrentVelocity(1000); + + float newOffset = mSheetDelegate.getCurrentOffsetPx() + + getFlingDistance(-mVelocityTracker.getYVelocity()); + + mSheetDelegate.setSheetOffset( + MathUtils.clamp(newOffset, mSheetDelegate.getMinOffsetPx(), + mSheetDelegate.getMaxOffsetPx()), + true); + } + + return true; + } + + /** + * @return Whether or not a gesture is currently being detected as a scroll. + */ + public boolean isScrolling() { + return mIsScrolling; + } + + /** + * Creates an unadjusted version of a MotionEvent. + * @param e The original event. + * @return The unadjusted version of the event. + */ + private MotionEvent createRawMotionEvent(MotionEvent e) { + MotionEvent rawEvent = MotionEvent.obtain(e); + rawEvent.setLocation(e.getRawX(), e.getRawY()); + return rawEvent; + } + + /** + * Gets the distance of a fling based on the velocity and the base animation time. This formula + * assumes the deceleration curve is quadratic (t^2), hence the displacement formula should be: + * displacement = initialVelocity * duration / 2. + * @param velocity The velocity of the fling. + * @return The distance the fling would cover. + */ + private float getFlingDistance(float velocity) { + // This includes conversion from seconds to ms. + return velocity * BASE_ANIMATION_DURATION_MS / 2000f; + } +} diff --git a/chromium/components/browser_ui/android/bottomsheet/internal/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetSwipeDetectorTest.java b/chromium/components/browser_ui/android/bottomsheet/internal/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetSwipeDetectorTest.java new file mode 100644 index 00000000000..a3a557a9cfa --- /dev/null +++ b/chromium/components/browser_ui/android/bottomsheet/internal/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetSwipeDetectorTest.java @@ -0,0 +1,319 @@ +// Copyright 2017 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.components.browser_ui.bottomsheet; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import android.view.MotionEvent; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.MockitoAnnotations; +import org.robolectric.annotation.Config; + +import org.chromium.base.MathUtils; +import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.components.browser_ui.bottomsheet.BottomSheetSwipeDetector.SwipeableBottomSheet; + +import java.util.ArrayList; +import java.util.List; + +/** + * Unit tests for the {@link BottomSheetSwipeDetector} class. + */ +@RunWith(BaseRobolectricTestRunner.class) +@Config(manifest = Config.NONE) +public final class BottomSheetSwipeDetectorTest { + /** The minimum height of the bottom sheet. */ + private static final float MIN_SHEET_OFFSET = 100; + + /** An arbitrary screen height. */ + private static final float SCREEN_HEIGHT = 1000; + + /** An instance of the mock swipable sheet. */ + private MockSwipeableBottomSheet mSwipeableBottomSheet; + + /** The swipe detector to process motion events. */ + private BottomSheetSwipeDetector mSwipeDetector; + + /** A mock implementation of a swipeable bottom sheet. */ + private static class MockSwipeableBottomSheet implements SwipeableBottomSheet { + /** The minimum offset of the sheet. */ + private final float mMinOffset; + + /** The maximum offset of the sheet. */ + private final float mMaxOffset; + + /** Whether the content in the sheet is currently scrolled to the top. */ + public boolean isContentScrolledToTop; + + /** Whether the sheet should currently be animating. */ + public boolean shouldBeAnimating; + + /** The current offset of the bottom sheet. */ + private float mCurrentSheetOffset; + + public MockSwipeableBottomSheet(float minOffset, float maxOffset) { + mMinOffset = minOffset; + mMaxOffset = maxOffset; + + // The sheet should be initialized at the minimum state. + mCurrentSheetOffset = mMinOffset; + + isContentScrolledToTop = true; + } + + @Override + public boolean isContentScrolledToTop() { + return isContentScrolledToTop; + } + + @Override + public float getCurrentOffsetPx() { + return mCurrentSheetOffset; + } + + @Override + public float getMinOffsetPx() { + return mMinOffset; + } + + @Override + public float getMaxOffsetPx() { + return mMaxOffset; + } + + @Override + public boolean isTouchEventInToolbar(MotionEvent event) { + // This will be implementation specific in practice. This checks that the motion event + // occured above the bottom of the toolbar. + return event.getRawY() < (mMaxOffset - mCurrentSheetOffset) + mMinOffset; + } + + @Override + public boolean shouldGestureMoveSheet( + MotionEvent initialDownEvent, MotionEvent currentEvent) { + return true; + } + + @Override + public void setSheetOffset(float offset, boolean shouldAnimate) { + mCurrentSheetOffset = offset; + shouldBeAnimating = shouldAnimate; + } + } + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + mSwipeableBottomSheet = new MockSwipeableBottomSheet(MIN_SHEET_OFFSET, SCREEN_HEIGHT); + mSwipeDetector = new BottomSheetSwipeDetector(null, mSwipeableBottomSheet); + } + + /** + * Create a list of motion events simulating a scroll event stream from (x1, y1) to (x2, y2) + * and apply it to the provided swipe detector. + * @param x1 The start x. + * @param y1 The start y. + * @param x2 The end x. + * @param y2 The end y. + * @param detector The detector to apply the swipe to. + * @param endScroll Whether or not to include the up event at the end of the stream. + * @return A list of motion events. + */ + private static void performScroll(float x1, float y1, float x2, float y2, + BottomSheetSwipeDetector detector, boolean endScroll) { + int moveEventCount = 10; + + ArrayList<MotionEvent> eventStream = new ArrayList<>(); + float xInterval = (x2 - x1) / moveEventCount; + float yInterval = (y2 - y1) / moveEventCount; + eventStream.add(MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, x1, y1, 0)); + for (int i = 0; i < moveEventCount; i++) { + eventStream.add(MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, + x1 + ((i + 1) * xInterval), y1 + ((i + 1) * yInterval), 0)); + } + if (endScroll) eventStream.add(MotionEvent.obtain(0, 0, MotionEvent.ACTION_UP, x2, y2, 0)); + + applyGestureStream(eventStream, detector); + } + + /** + * Apply a list of events to a swipe detector. + * @param stream The list of motion events to apply to the detector. + * @param detector The detector to apply the swipe to. + */ + private static void applyGestureStream( + List<MotionEvent> stream, BottomSheetSwipeDetector detector) { + for (MotionEvent e : stream) { + if (!detector.isScrolling()) { + detector.onInterceptTouchEvent(e); + } else { + detector.onTouchEvent(e); + } + } + } + + /** Test that the sheet moves when scrolled up from min height. */ + @Test + public void testScrollToolbarUp_minHeight() { + assertEquals("The sheet should be at the minimum state.", MIN_SHEET_OFFSET, + mSwipeableBottomSheet.getCurrentOffsetPx(), MathUtils.EPSILON); + final float halfScreenHeight = SCREEN_HEIGHT / 2f; + + // Scrolling up half the screen should put the sheet at half + the min offset. + performScroll(0, SCREEN_HEIGHT, 0, halfScreenHeight, mSwipeDetector, true); + + assertEquals("The sheet is not at the correct height.", halfScreenHeight + MIN_SHEET_OFFSET, + mSwipeableBottomSheet.getCurrentOffsetPx(), MathUtils.EPSILON); + assertTrue("The sheet should be set to animate.", mSwipeableBottomSheet.shouldBeAnimating); + } + + /** Test that the sheet is not told to animate mid-stream. */ + @Test + public void testScrollToolbarUp_minHeight_noUpEvent() { + final float halfScreenHeight = SCREEN_HEIGHT / 2f; + + performScroll(0, SCREEN_HEIGHT, 0, halfScreenHeight, mSwipeDetector, false); + + assertEquals("The sheet is not at the correct height.", halfScreenHeight + MIN_SHEET_OFFSET, + mSwipeableBottomSheet.getCurrentOffsetPx(), MathUtils.EPSILON); + assertFalse( + "The sheet should not be set to animate.", mSwipeableBottomSheet.shouldBeAnimating); + } + + /** Test that the sheet does not move when scrolled up from max height. */ + @Test + public void testScrollToolbarUp_maxHeight() { + // Init the sheet to be full height. + mSwipeableBottomSheet.setSheetOffset(SCREEN_HEIGHT, false); + + assertEquals("The sheet should be at the maximum state.", SCREEN_HEIGHT, + mSwipeableBottomSheet.getCurrentOffsetPx(), MathUtils.EPSILON); + + performScroll(0, 0, 0, -500, mSwipeDetector, true); + + assertEquals("The sheet should still be at the maximum state.", SCREEN_HEIGHT, + mSwipeableBottomSheet.getCurrentOffsetPx(), MathUtils.EPSILON); + assertFalse( + "The sheet should not be set to animate.", mSwipeableBottomSheet.shouldBeAnimating); + } + + /** Test that the sheet does not move when scrolled down from min height. */ + @Test + public void testScrollToolbarDown_minHeight() { + assertEquals("The sheet should be at the minimum state.", MIN_SHEET_OFFSET, + mSwipeableBottomSheet.getCurrentOffsetPx(), MathUtils.EPSILON); + + performScroll(0, SCREEN_HEIGHT, 0, SCREEN_HEIGHT + 500, mSwipeDetector, true); + + assertEquals("The sheet should still be at the minimum state.", MIN_SHEET_OFFSET, + mSwipeableBottomSheet.getCurrentOffsetPx(), MathUtils.EPSILON); + assertFalse( + "The sheet should not be set to animate.", mSwipeableBottomSheet.shouldBeAnimating); + } + + /** Test that the sheet moves when scrolled down from max height. */ + @Test + public void testScrollToolbarDown_maxHeight() { + // Init the sheet to be full height. + mSwipeableBottomSheet.setSheetOffset(SCREEN_HEIGHT, false); + + assertEquals("The sheet should be at the maximum state.", SCREEN_HEIGHT, + mSwipeableBottomSheet.getCurrentOffsetPx(), MathUtils.EPSILON); + final float halfScreenHeight = SCREEN_HEIGHT / 2f; + + // Scrolling down half the screen should put the sheet at half height. + performScroll(0, 0, 0, halfScreenHeight, mSwipeDetector, true); + + assertEquals("The sheet is not at the correct height.", halfScreenHeight, + mSwipeableBottomSheet.getCurrentOffsetPx(), MathUtils.EPSILON); + assertTrue("The sheet should be set to animate.", mSwipeableBottomSheet.shouldBeAnimating); + } + + /** + * Test that the sheet moves when scrolled down from max height while the content has been + * scrolled. + */ + @Test + public void testScrollToolbarDown_maxHeight_contentScrolled() { + // Init the sheet to be full height. + mSwipeableBottomSheet.setSheetOffset(SCREEN_HEIGHT, false); + + assertEquals("The sheet should be at the maximum state.", SCREEN_HEIGHT, + mSwipeableBottomSheet.getCurrentOffsetPx(), MathUtils.EPSILON); + final float halfScreenHeight = SCREEN_HEIGHT / 2f; + + // Scrolling down half the screen should put the sheet at half height, regardless of the + // state of the content. + performScroll(0, 0, 0, halfScreenHeight, mSwipeDetector, true); + + assertEquals("The sheet is not at the correct height.", halfScreenHeight, + mSwipeableBottomSheet.getCurrentOffsetPx(), MathUtils.EPSILON); + assertTrue("The sheet should be set to animate.", mSwipeableBottomSheet.shouldBeAnimating); + } + + /** Test that the sheet does not move when a scroll is not sufficiently in the up direction. */ + @Test + public void testScrollToolbarDiagonal_minHeight() { + assertEquals("The sheet should be at the minimum state.", MIN_SHEET_OFFSET, + mSwipeableBottomSheet.getCurrentOffsetPx(), MathUtils.EPSILON); + final float halfScreenHeight = SCREEN_HEIGHT / 2f; + + performScroll( + 0, halfScreenHeight, halfScreenHeight, halfScreenHeight, mSwipeDetector, true); + + assertEquals("The sheet should still be at the minimum state.", MIN_SHEET_OFFSET, + mSwipeableBottomSheet.getCurrentOffsetPx(), MathUtils.EPSILON); + assertFalse( + "The sheet should not be set to animate.", mSwipeableBottomSheet.shouldBeAnimating); + } + + /** + * Test that the sheet does not move when the content is scrolled up and the sheet is at max + * height. + */ + @Test + public void testScrollContent_maxHeight() { + // Init the sheet to be full height. + mSwipeableBottomSheet.setSheetOffset(SCREEN_HEIGHT, false); + + // Content is scrolled some amount. + mSwipeableBottomSheet.isContentScrolledToTop = false; + + final float halfScreenHeight = SCREEN_HEIGHT / 2f; + + // Scroll down half the screen. The sheet should not move since the content is scrolled. + performScroll(0, halfScreenHeight, 0, SCREEN_HEIGHT, mSwipeDetector, true); + + assertEquals("The sheet should still be at the maximum state.", SCREEN_HEIGHT, + mSwipeableBottomSheet.getCurrentOffsetPx(), MathUtils.EPSILON); + } + + /** + * Test that the sheet moves when a scroll occurs on the body of the sheet. Content should only + * scroll if the sheet is at max height. + */ + @Test + public void testScrollContent_halfHeight() { + final float halfScreenHeight = SCREEN_HEIGHT / 2f; + + // Init the sheet to be half height. + mSwipeableBottomSheet.setSheetOffset(halfScreenHeight, false); + + // Content is scrolled some amount. + mSwipeableBottomSheet.isContentScrolledToTop = false; + + // Scroll down on the content, the sheet should move. + performScroll(0, halfScreenHeight / 2f, 0, SCREEN_HEIGHT, mSwipeDetector, true); + + assertEquals("The sheet should be at the minimum state.", MIN_SHEET_OFFSET, + mSwipeableBottomSheet.getCurrentOffsetPx(), MathUtils.EPSILON); + } +} diff --git a/chromium/components/browser_ui/android/bottomsheet/internal/java/src/org/chromium/components/browser_ui/bottomsheet/TouchRestrictingFrameLayout.java b/chromium/components/browser_ui/android/bottomsheet/internal/java/src/org/chromium/components/browser_ui/bottomsheet/TouchRestrictingFrameLayout.java new file mode 100644 index 00000000000..45d7f47cc8e --- /dev/null +++ b/chromium/components/browser_ui/android/bottomsheet/internal/java/src/org/chromium/components/browser_ui/bottomsheet/TouchRestrictingFrameLayout.java @@ -0,0 +1,50 @@ +// Copyright 2018 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.components.browser_ui.bottomsheet; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.widget.FrameLayout; + +/** + * A specialized FrameLayout that is capable of ignoring all user input based on the state of + * the bottom sheet. + */ +class TouchRestrictingFrameLayout extends FrameLayout { + /** A handle to the bottom sheet. */ + private BottomSheet mBottomSheet; + + public TouchRestrictingFrameLayout(Context context, AttributeSet atts) { + super(context, atts); + } + + /** + * @param sheet The bottom sheet. + */ + public void setBottomSheet(BottomSheet sheet) { + mBottomSheet = sheet; + } + + /** + * @return Whether touch is enabled. + */ + private boolean isTouchDisabled() { + return mBottomSheet == null + || mBottomSheet.getSheetState() == BottomSheetController.SheetState.SCROLLING; + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent event) { + if (isTouchDisabled()) return false; + return super.onInterceptTouchEvent(event); + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + if (isTouchDisabled()) return false; + return super.onTouchEvent(event); + } +} diff --git a/chromium/components/browser_ui/android/bottomsheet/java/res/layout/bottom_sheet.xml b/chromium/components/browser_ui/android/bottomsheet/java/res/layout/bottom_sheet.xml new file mode 100644 index 00000000000..37ce7fcab57 --- /dev/null +++ b/chromium/components/browser_ui/android/bottomsheet/java/res/layout/bottom_sheet.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2018 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. --> + +<org.chromium.components.browser_ui.bottomsheet.BottomSheet + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/bottom_sheet" + android:layout_width="match_parent" + android:layout_height="wrap_content" > + + <org.chromium.components.browser_ui.bottomsheet.TouchRestrictingFrameLayout + android:id="@+id/bottom_sheet_content" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@drawable/top_round" /> + + <FrameLayout + android:id="@+id/bottom_sheet_control_container" + android:layout_width="match_parent" + android:layout_height="wrap_content" > + + <view + class="org.chromium.components.browser_ui.bottomsheet.TouchRestrictingFrameLayout" + android:id="@+id/bottom_sheet_toolbar_container" + android:layout_width="match_parent" + android:layout_height="wrap_content" > + + <View + android:id="@+id/bottom_sheet_toolbar" + android:layout_width="match_parent" + android:layout_height="@dimen/bottom_sheet_peek_height" /> + </view> + + </FrameLayout> + + <FrameLayout + android:id="@+id/bottom_sheet_snackbar_container" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="start|bottom" /> + +</org.chromium.components.browser_ui.bottomsheet.BottomSheet> diff --git a/chromium/components/browser_ui/android/bottomsheet/java/res/values/dimens.xml b/chromium/components/browser_ui/android/bottomsheet/java/res/values/dimens.xml new file mode 100644 index 00000000000..d795be2ea38 --- /dev/null +++ b/chromium/components/browser_ui/android/bottomsheet/java/res/values/dimens.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2020 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 xmlns:tools="http://schemas.android.com/tools"> + <dimen name="bottom_sheet_min_full_half_distance">140dp</dimen> + <dimen name="bottom_sheet_peek_height">56dp</dimen> + <dimen name="bottom_sheet_toolbar_shadow_height">16dp</dimen> + <dimen name="bottom_sheet_shadow_top_offset">10dp</dimen> +</resources> + diff --git a/chromium/components/browser_ui/android/bottomsheet/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetController.java b/chromium/components/browser_ui/android/bottomsheet/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetController.java new file mode 100644 index 00000000000..d24e41afe7b --- /dev/null +++ b/chromium/components/browser_ui/android/bottomsheet/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetController.java @@ -0,0 +1,158 @@ +// Copyright 2020 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.components.browser_ui.bottomsheet; + +import androidx.annotation.IntDef; + +import org.chromium.components.browser_ui.widget.scrim.ScrimCoordinator; +import org.chromium.ui.modelutil.PropertyModel; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * The public interface for the bottom sheet's controller. Features wishing to show content in the + * sheet UI must implement {@link BottomSheetContent} and call + * {@link #requestShowContent(BottomSheetContent, boolean)} which will return true if the content + * was actually shown (see full doc on method). + */ +public interface BottomSheetController { + /** The different states that the bottom sheet can have. */ + @IntDef({SheetState.NONE, SheetState.HIDDEN, SheetState.PEEK, SheetState.HALF, SheetState.FULL, + SheetState.SCROLLING}) + @Retention(RetentionPolicy.SOURCE) + @interface SheetState { + /** + * NONE is for internal use only and indicates the sheet is not currently + * transitioning between states. + */ + int NONE = -1; + // Values are used for indexing mStateRatios, should start from 0 + // and can't have gaps. Additionally order is important for these, + // they go from smallest to largest. + int HIDDEN = 0; + int PEEK = 1; + int HALF = 2; + int FULL = 3; + + int SCROLLING = 4; + } + + /** + * The different reasons that the sheet's state can change. + * + * Needs to stay in sync with BottomSheet.StateChangeReason in enums.xml. These values are + * persisted to logs. Entries should not be renumbered and numeric values should never be + * reused. + */ + @IntDef({StateChangeReason.NONE, StateChangeReason.SWIPE, StateChangeReason.BACK_PRESS, + StateChangeReason.TAP_SCRIM, StateChangeReason.NAVIGATION, + StateChangeReason.COMPOSITED_UI, StateChangeReason.VR, StateChangeReason.PROMOTE_TAB, + StateChangeReason.OMNIBOX_FOCUS, StateChangeReason.MAX_VALUE}) + @Retention(RetentionPolicy.SOURCE) + @interface StateChangeReason { + int NONE = 0; + int SWIPE = 1; + int BACK_PRESS = 2; + int TAP_SCRIM = 3; + int NAVIGATION = 4; + int COMPOSITED_UI = 5; + int VR = 6; + int PROMOTE_TAB = 7; + int OMNIBOX_FOCUS = 8; + int MAX_VALUE = OMNIBOX_FOCUS; + } + + /** + * Request that some content be shown in the bottom sheet. + * @param content The content to be shown in the bottom sheet. + * @param animate Whether the appearance of the bottom sheet should be animated. + * @return True if the content was shown, false if it was suppressed. Content is suppressed if + * higher priority content is in the sheet, the sheet is expanded beyond the peeking + * state, or the browser is in a mode that does not support showing the sheet. + */ + boolean requestShowContent(BottomSheetContent content, boolean animate); + + /** + * Hide content shown in the bottom sheet. If the content is not showing, this call retracts the + * request to show it. + * @param content The content to be hidden. + * @param animate Whether the sheet should animate when hiding. + * @param hideReason The reason that the content is being hidden. + */ + void hideContent( + BottomSheetContent content, boolean animate, @StateChangeReason int hideReason); + + void hideContent(BottomSheetContent content, boolean animate); + + /** @param observer The observer to add. */ + void addObserver(BottomSheetObserver observer); + + /** @param observer The observer to remove. */ + void removeObserver(BottomSheetObserver observer); + + /** + * Expand the sheet. If there is no content in the sheet, this is a noop. + */ + void expandSheet(); + + /** + * Collapse the current sheet to peek state. Sheet may not change the state if the state + * is not allowed. + * @param animate {@code true} for animation effect. + * @return {@code true} if the sheet could go to the peek state. + */ + boolean collapseSheet(boolean animate); + + /** @return The content currently showing in the bottom sheet. */ + BottomSheetContent getCurrentSheetContent(); + + /** @return The current state of the bottom sheet. */ + @SheetState + int getSheetState(); + + /** @return The target state of the bottom sheet (usually during animations). */ + @SheetState + int getTargetSheetState(); + + /** @return Whether the bottom sheet is currently open (expanded beyond peek state). */ + boolean isSheetOpen(); + + /** @return Whether the bottom sheet is in the process of hiding. */ + boolean isSheetHiding(); + + /** @return The current offset from the bottom of the screen that the sheet is in px. */ + int getCurrentOffset(); + + /** + * @return The height of the bottom sheet's container in px. This will return 0 if the sheet has + * not been initialized (content has not been requested). + */ + int getContainerHeight(); + + /** @return The height of the shadow above the bottom sheet in px. */ + int getTopShadowHeight(); + + /** + * @return The srcim's coordinator. This can be used to customize the bottom sheet's interaction + * with the scrim if the default behavior is not desired -- fading in behind the sheet + * as the sheet is expanded. + */ + ScrimCoordinator getScrimCoordinator(); + + /** + * This method provides a property model that can be used to show the scrim behind the bottom + * sheet. This can be used in conjunction with {@link #getScrimCoordinator()} to customize the + * scrim's behavior. While this method is not required to show the scrim, this method returns + * a model set up to appear behnind the sheet. Common usage is the following: + * + * PropertyModel params = controller.createScrimParams(); + * // further modify params + * controller.getScrimCoordinator().showScrim(params); + * + * @return A property model used to show the scrim behind the bottom sheet. + */ + PropertyModel createScrimParams(); +} diff --git a/chromium/components/browser_ui/android/bottomsheet/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetObserver.java b/chromium/components/browser_ui/android/bottomsheet/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetObserver.java new file mode 100644 index 00000000000..e5c2ae2687c --- /dev/null +++ b/chromium/components/browser_ui/android/bottomsheet/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetObserver.java @@ -0,0 +1,57 @@ +// Copyright 2017 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.components.browser_ui.bottomsheet; + +import androidx.annotation.Nullable; + +import org.chromium.components.browser_ui.bottomsheet.BottomSheetController.SheetState; +import org.chromium.components.browser_ui.bottomsheet.BottomSheetController.StateChangeReason; + +/** + * An interface for notifications about the state of the bottom sheet. + */ +public interface BottomSheetObserver { + /** + * A notification that the sheet has been opened, meaning the sheet is any height greater + * than its peeking state. + * @param reason The {@link StateChangeReason} that the sheet was opened. + */ + void onSheetOpened(@StateChangeReason int reason); + + /** + * A notification that the sheet has closed, meaning the sheet has reached its peeking state. + * @param reason The {@link StateChangeReason} that the sheet was closed. + */ + void onSheetClosed(@StateChangeReason int reason); + + /** + * An event for when the sheet's offset from the bottom of the screen changes. + * + * @param heightFraction The fraction of the way to the fully expanded state that the sheet + * is. This will be 0.0f when the sheet is hidden or scrolled off-screen + * and 1.0f when the sheet is completely expanded. + * @param offsetPx The offset of the top of the sheet from the bottom of the screen in pixels. + */ + void onSheetOffsetChanged(float heightFraction, float offsetPx); + + /** + * An event for when the sheet changes state. + * @param newState The new sheet state. See {@link SheetState}. + */ + void onSheetStateChanged(@SheetState int newState); + + /** + * An event for when the sheet reaches its full peeking height. This is called when the sheet + * is finished being scrolled back on-screen or finishes animating to its peeking state. This + * is also called when going back to the peeking state after the sheet has been opened. + */ + void onSheetFullyPeeked(); + + /** + * An event for when the sheet content changes. + * @param newContent The new {@link BottomSheetContent}, or null if the sheet has no content. + */ + void onSheetContentChanged(@Nullable BottomSheetContent newContent); +} diff --git a/chromium/components/browser_ui/android/bottomsheet/java/src/org/chromium/components/browser_ui/bottomsheet/EmptyBottomSheetObserver.java b/chromium/components/browser_ui/android/bottomsheet/java/src/org/chromium/components/browser_ui/bottomsheet/EmptyBottomSheetObserver.java new file mode 100644 index 00000000000..c758da5acf5 --- /dev/null +++ b/chromium/components/browser_ui/android/bottomsheet/java/src/org/chromium/components/browser_ui/bottomsheet/EmptyBottomSheetObserver.java @@ -0,0 +1,30 @@ +// Copyright 2017 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.components.browser_ui.bottomsheet; + +import org.chromium.components.browser_ui.bottomsheet.BottomSheetController.StateChangeReason; + +/** + * An empty base implementation of the {@link BottomSheetObserver} interface. + */ +public class EmptyBottomSheetObserver implements BottomSheetObserver { + @Override + public void onSheetOpened(@StateChangeReason int reason) {} + + @Override + public void onSheetClosed(@StateChangeReason int reason) {} + + @Override + public void onSheetOffsetChanged(float heightFraction, float offsetPx) {} + + @Override + public void onSheetStateChanged(int newState) {} + + @Override + public void onSheetFullyPeeked() {} + + @Override + public void onSheetContentChanged(BottomSheetContent newContent) {} +} diff --git a/chromium/components/browser_ui/android/bottomsheet/java/src/org/chromium/components/browser_ui/bottomsheet/ManagedBottomSheetController.java b/chromium/components/browser_ui/android/bottomsheet/java/src/org/chromium/components/browser_ui/bottomsheet/ManagedBottomSheetController.java new file mode 100644 index 00000000000..aa045e501f5 --- /dev/null +++ b/chromium/components/browser_ui/android/bottomsheet/java/src/org/chromium/components/browser_ui/bottomsheet/ManagedBottomSheetController.java @@ -0,0 +1,54 @@ +// Copyright 2020 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.components.browser_ui.bottomsheet; + +import org.chromium.ui.util.AccessibilityUtil; + +/** + * An interface for the owning object to manage interaction between the bottom sheet and the rest + * of the system. + */ +public interface ManagedBottomSheetController extends BottomSheetController { + /** + * Temporarily suppress the bottom sheet while other UI is showing. This will not itself change + * the content displayed by the sheet. + * @param reason The reason the sheet was suppressed. + * @return A token to unsuppress the sheet with. + */ + int suppressSheet(@StateChangeReason int reason); + + /** + * Unsuppress the bottom sheet. This may or may not affect the sheet depending on the state of + * the browser (i.e. the tab switcher may be showing). + * @param token The token that was received from suppressing the sheet. + */ + void unsuppressSheet(int token); + + /** + * For all contents that don't have a custom lifecycle, we remove them from show requests or + * hide it if it is currently shown. + */ + void clearRequestsAndHide(); + + /** + * Handle a back press event. By default this will return the bottom sheet to it's minimum / + * peeking state if it is open. However, the sheet's content has the opportunity to intercept + * this event and block the default behavior {@see BottomSheetContent#handleBackPress()}. + * @return {@code true} if the sheet or content handled the back press. + */ + boolean handleBackPress(); + + /** + * Set the hidden ratio of the browser controls. + * @param ratio The hidden ratio of the browser controls in range [0, 1]. + */ + void setBrowserControlsHiddenRatio(float ratio); + + /** @param accessibilityUtil A mechanism for testing whether accessibility is enabled. */ + void setAccssibilityUtil(AccessibilityUtil accessibilityUtil); + + /** Clean up any state maintained by the controller. */ + void destroy(); +} diff --git a/chromium/components/browser_ui/android/bottomsheet/test/BUILD.gn b/chromium/components/browser_ui/android/bottomsheet/test/BUILD.gn new file mode 100644 index 00000000000..f8c7f8b22fc --- /dev/null +++ b/chromium/components/browser_ui/android/bottomsheet/test/BUILD.gn @@ -0,0 +1,16 @@ +# Copyright 2020 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. + +import("//build/config/android/rules.gni") + +android_library("java") { + sources = [ "java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetTestSupport.java" ] + + deps = [ + "..:java", + "..:manager_java", + "../internal:java", + "//third_party/android_deps:androidx_annotation_annotation_java", + ] +} diff --git a/chromium/components/browser_ui/client_certificate/OWNERS b/chromium/components/browser_ui/client_certificate/OWNERS new file mode 100644 index 00000000000..bd8c1538b60 --- /dev/null +++ b/chromium/components/browser_ui/client_certificate/OWNERS @@ -0,0 +1,7 @@ +# Primary: +dmcardle@chromium.org + +# Secondary: +file://chrome/android/OWNERS + +# COMPONENT: Internals>Network>Auth diff --git a/chromium/components/browser_ui/client_certificate/android/BUILD.gn b/chromium/components/browser_ui/client_certificate/android/BUILD.gn new file mode 100644 index 00000000000..68a7aaf93bf --- /dev/null +++ b/chromium/components/browser_ui/client_certificate/android/BUILD.gn @@ -0,0 +1,58 @@ +# Copyright 2020 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. + +import("//build/config/android/rules.gni") + +android_resources("java_resources") { + custom_package = "org.chromium.components.browser_ui.client_certificate" + deps = [ + "//components/browser_ui/strings/android:browser_ui_strings_grd", + "//components/browser_ui/styles/android:java_resources", + ] +} + +generate_jni("jni_headers") { + sources = [ "java/src/org/chromium/components/browser_ui/client_certificate/SSLClientCertificateRequest.java" ] +} + +android_library("java") { + sources = [ "java/src/org/chromium/components/browser_ui/client_certificate/SSLClientCertificateRequest.java" ] + deps = [ + ":java_resources", + "//base:base_java", + "//base:jni_java", + "//content/public/android:content_java", + "//third_party/android_deps:androidx_appcompat_appcompat_java", + "//ui/android:ui_java", + ] + annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] +} + +source_set("android") { + sources = [ + "ssl_client_certificate_request.cc", + "ssl_client_certificate_request.h", + ] + deps = [ + ":jni_headers", + "//base", + "//content/public/browser", + "//net", + "//ui/android", + ] +} + +java_library("junit") { + # Platform checks are broken for Robolectric. See https://crbug.com/1071638. + bypass_platform_checks = true + testonly = true + sources = [ "java/src/org/chromium/components/browser_ui/client_certificate/SSLClientCertificateRequestTest.java" ] + deps = [ + ":java", + "//base:base_junit_test_support", + "//third_party/android_deps:robolectric_all_java", + "//third_party/junit", + "//third_party/mockito:mockito_java", + ] +} diff --git a/chromium/components/browser_ui/client_certificate/android/DEPS b/chromium/components/browser_ui/client_certificate/android/DEPS new file mode 100644 index 00000000000..20a2f7177eb --- /dev/null +++ b/chromium/components/browser_ui/client_certificate/android/DEPS @@ -0,0 +1,6 @@ +include_rules = [ + "+content/public/android/java/src/org/chromium/content_public", + "+content/public/browser", + "+net", + "+ui/android", +] diff --git a/chromium/components/browser_ui/client_certificate/android/java/src/org/chromium/components/browser_ui/client_certificate/SSLClientCertificateRequest.java b/chromium/components/browser_ui/client_certificate/android/java/src/org/chromium/components/browser_ui/client_certificate/SSLClientCertificateRequest.java new file mode 100644 index 00000000000..800cf88e521 --- /dev/null +++ b/chromium/components/browser_ui/client_certificate/android/java/src/org/chromium/components/browser_ui/client_certificate/SSLClientCertificateRequest.java @@ -0,0 +1,320 @@ +// 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.components.browser_ui.client_certificate; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.content.ActivityNotFoundException; +import android.content.Context; +import android.content.DialogInterface.OnClickListener; +import android.security.KeyChain; +import android.security.KeyChainAliasCallback; +import android.security.KeyChainException; +import android.util.Log; + +import androidx.annotation.VisibleForTesting; +import androidx.appcompat.app.AlertDialog; + +import org.chromium.base.ContextUtils; +import org.chromium.base.ThreadUtils; +import org.chromium.base.annotations.CalledByNative; +import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.NativeMethods; +import org.chromium.base.task.AsyncTask; +import org.chromium.base.task.PostTask; +import org.chromium.content_public.browser.UiThreadTaskTraits; +import org.chromium.ui.UiUtils; +import org.chromium.ui.base.WindowAndroid; + +import java.security.Principal; +import java.security.PrivateKey; +import java.security.cert.CertificateEncodingException; +import java.security.cert.X509Certificate; + +import javax.security.auth.x500.X500Principal; + +/** + * Handles selection of client certificate on the Java side. This class is responsible for selection + * of the client certificate to be used for authentication and retrieval of the private key and full + * certificate chain. + * + * The entry point is selectClientCertificate() and it will be called on the UI thread. Then the + * class will construct and run an appropriate CertAsyncTask, that will run in background, and + * finally pass the results back to the UI thread, which will return to the native code. + */ +@JNINamespace("browser_ui") +public class SSLClientCertificateRequest { + static final String TAG = "SSLClientCertificateRequest"; + + /** + * Implementation for anynchronous task of handling the certificate request. This + * AsyncTask retrieves the authentication material from the system key store. + * The key store is accessed in background, as the APIs being exercised + * may be blocking. The results are posted back to native on the UI thread. + */ + private static class CertAsyncTaskKeyChain extends AsyncTask<Void> { + // These fields will store the results computed in doInBackground so that they can be posted + // back in onPostExecute. + private byte[][] mEncodedChain; + private PrivateKey mPrivateKey; + + // Pointer to the native certificate request needed to return the results. + private final long mNativePtr; + + @SuppressLint("StaticFieldLeak") // TODO(crbug.com/807729): Remove and fix. + final Context mContext; + final String mAlias; + + CertAsyncTaskKeyChain(Context context, long nativePtr, String alias) { + mNativePtr = nativePtr; + mContext = context; + assert alias != null; + mAlias = alias; + } + + @Override + protected Void doInBackground() { + String alias = getAlias(); + if (alias == null) return null; + + PrivateKey key = getPrivateKey(alias); + X509Certificate[] chain = getCertificateChain(alias); + + if (key == null || chain == null || chain.length == 0) { + Log.w(TAG, "Empty client certificate chain?"); + return null; + } + + // Encode the certificate chain. + byte[][] encodedChain = new byte[chain.length][]; + try { + for (int i = 0; i < chain.length; ++i) { + encodedChain[i] = chain[i].getEncoded(); + } + } catch (CertificateEncodingException e) { + Log.w(TAG, "Could not retrieve encoded certificate chain: " + e); + return null; + } + + mEncodedChain = encodedChain; + mPrivateKey = key; + return null; + } + + @Override + protected void onPostExecute(Void result) { + ThreadUtils.assertOnUiThread(); + SSLClientCertificateRequestJni.get().onSystemRequestCompletion( + mNativePtr, mEncodedChain, mPrivateKey); + } + + private String getAlias() { + return mAlias; + } + + private PrivateKey getPrivateKey(String alias) { + try { + return KeyChain.getPrivateKey(mContext, alias); + } catch (KeyChainException e) { + Log.w(TAG, "KeyChainException when looking for '" + alias + "' certificate"); + return null; + } catch (InterruptedException e) { + Log.w(TAG, "InterruptedException when looking for '" + alias + "'certificate"); + return null; + } + } + + private X509Certificate[] getCertificateChain(String alias) { + try { + return KeyChain.getCertificateChain(mContext, alias); + } catch (KeyChainException e) { + Log.w(TAG, "KeyChainException when looking for '" + alias + "' certificate"); + return null; + } catch (InterruptedException e) { + Log.w(TAG, "InterruptedException when looking for '" + alias + "'certificate"); + return null; + } + } + } + + /** + * The system KeyChain API will call us back on the alias() method, passing the alias of the + * certificate selected by the user. + */ + private static class KeyChainCertSelectionCallback implements KeyChainAliasCallback { + private final long mNativePtr; + private final Context mContext; + + KeyChainCertSelectionCallback(Context context, long nativePtr) { + mContext = context; + mNativePtr = nativePtr; + } + + @Override + public void alias(final String alias) { + // This is called by KeyChainActivity in a background thread. Post task to + // handle the certificate selection on the UI thread. + PostTask.runOrPostTask(UiThreadTaskTraits.DEFAULT, () -> { + if (alias == null) { + // No certificate was selected. + PostTask.runOrPostTask(UiThreadTaskTraits.DEFAULT, + () + -> SSLClientCertificateRequestJni.get() + .onSystemRequestCompletion(mNativePtr, null, null)); + } else { + new CertAsyncTaskKeyChain(mContext, mNativePtr, alias) + .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } + }); + } + } + + /** + * Wrapper class for the static KeyChain#choosePrivateKeyAlias method to facilitate testing. + */ + @VisibleForTesting + static class KeyChainCertSelectionWrapper { + private final Activity mActivity; + private final KeyChainAliasCallback mCallback; + private final String[] mKeyTypes; + private final Principal[] mPrincipalsForCallback; + private final String mHostName; + private final int mPort; + private final String mAlias; + + public KeyChainCertSelectionWrapper(Activity activity, KeyChainAliasCallback callback, + String[] keyTypes, Principal[] principalsForCallback, String hostName, int port, + String alias) { + mActivity = activity; + mCallback = callback; + mKeyTypes = keyTypes; + mPrincipalsForCallback = principalsForCallback; + mHostName = hostName; + mPort = port; + mAlias = alias; + } + + /** + * Calls KeyChain#choosePrivateKeyAlias with the provided arguments. + */ + public void choosePrivateKeyAlias() throws ActivityNotFoundException { + KeyChain.choosePrivateKeyAlias(mActivity, mCallback, mKeyTypes, mPrincipalsForCallback, + mHostName, mPort, mAlias); + } + } + + /** + * Dialog that explains to the user that client certificates aren't supported on their operating + * system. Separated out into its own class to allow Robolectric unit testing of + * maybeShowCertSelection without depending on Chrome resources. + */ + @VisibleForTesting + static class CertSelectionFailureDialog { + private final Context mContext; + + public CertSelectionFailureDialog(Context context) { + mContext = context; + } + + /** + * Builds and shows the dialog. + */ + public void show() { + final AlertDialog.Builder builder = new UiUtils.CompatibleAlertDialogBuilder( + mContext, R.style.Theme_Chromium_AlertDialog); + builder.setTitle(R.string.client_cert_unsupported_title) + .setMessage(R.string.client_cert_unsupported_message) + .setNegativeButton(R.string.close, + (OnClickListener) (dialog, which) + -> { + // Do nothing + }); + builder.show(); + } + } + + /** + * Create a new asynchronous request to select a client certificate. + * + * @param nativePtr The native object responsible for this request. + * @param window A WindowAndroid instance. + * @param keyTypes The list of supported key exchange types. + * @param encodedPrincipals The list of CA DistinguishedNames. + * @param hostName The server host name is available (empty otherwise). + * @param port The server port if available (0 otherwise). + * @return true on success. + * Note that nativeOnSystemRequestComplete will be called iff this method returns true. + */ + @CalledByNative + private static boolean selectClientCertificate(final long nativePtr, final WindowAndroid window, + final String[] keyTypes, byte[][] encodedPrincipals, final String hostName, + final int port) { + ThreadUtils.assertOnUiThread(); + + // Use the context for the failure dialog in case the activity doesn't have the correct + // resources. + final Context context = window.getContext().get(); + final Activity activity = ContextUtils.activityFromContext(context); + if (activity == null) { + Log.w(TAG, "Certificate request on GC'd activity."); + return false; + } + + // Build the list of principals from encoded versions. + Principal[] principals = null; + if (encodedPrincipals.length > 0) { + principals = new X500Principal[encodedPrincipals.length]; + try { + for (int n = 0; n < encodedPrincipals.length; n++) { + principals[n] = new X500Principal(encodedPrincipals[n]); + } + } catch (Exception e) { + Log.w(TAG, "Exception while decoding issuers list: " + e); + return false; + } + } + + KeyChainCertSelectionCallback callback = + new KeyChainCertSelectionCallback(activity.getApplicationContext(), nativePtr); + KeyChainCertSelectionWrapper keyChain = new KeyChainCertSelectionWrapper( + activity, callback, keyTypes, principals, hostName, port, null); + maybeShowCertSelection(keyChain, callback, new CertSelectionFailureDialog(context)); + + // We've taken ownership of the native ssl request object. + return true; + } + + /** + * Attempt to show the certificate selection dialog and shows the provided + * CertSelectionFailureDialog if the platform's cert selection activity can't be found. + */ + @VisibleForTesting + static void maybeShowCertSelection(KeyChainCertSelectionWrapper keyChain, + KeyChainAliasCallback callback, CertSelectionFailureDialog failureDialog) { + try { + keyChain.choosePrivateKeyAlias(); + } catch (ActivityNotFoundException e) { + // This exception can be hit when a platform is missing the activity to select + // a client certificate. It gets handled here to avoid a crash. + // Complete the callback without selecting a certificate. + callback.alias(null); + // Show a dialog letting the user know that the system does not support + // client certificate selection. + failureDialog.show(); + } + } + + public static void notifyClientCertificatesChangedOnIOThread() { + Log.d(TAG, "ClientCertificatesChanged!"); + SSLClientCertificateRequestJni.get().notifyClientCertificatesChangedOnIOThread(); + } + + @NativeMethods + interface Natives { + void notifyClientCertificatesChangedOnIOThread(); + // Called to pass request results to native side. + void onSystemRequestCompletion(long requestPtr, byte[][] certChain, PrivateKey privateKey); + } +} diff --git a/chromium/components/browser_ui/client_certificate/android/java/src/org/chromium/components/browser_ui/client_certificate/SSLClientCertificateRequestTest.java b/chromium/components/browser_ui/client_certificate/android/java/src/org/chromium/components/browser_ui/client_certificate/SSLClientCertificateRequestTest.java new file mode 100644 index 00000000000..2f3135f4106 --- /dev/null +++ b/chromium/components/browser_ui/client_certificate/android/java/src/org/chromium/components/browser_ui/client_certificate/SSLClientCertificateRequestTest.java @@ -0,0 +1,63 @@ +// 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.components.browser_ui.client_certificate; + +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; + +import android.content.ActivityNotFoundException; +import android.security.KeyChainAliasCallback; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.annotation.Config; + +import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.components.browser_ui.client_certificate.SSLClientCertificateRequest.CertSelectionFailureDialog; +import org.chromium.components.browser_ui.client_certificate.SSLClientCertificateRequest.KeyChainCertSelectionWrapper; + +/** + * Unit tests for the SSLClientCertificateRequest class. + */ +@RunWith(BaseRobolectricTestRunner.class) +@Config(manifest = Config.NONE) +public class SSLClientCertificateRequestTest { + @Mock + private KeyChainCertSelectionWrapper mKeyChainMock; + @Mock + private KeyChainAliasCallback mCallbackMock; + @Mock + private CertSelectionFailureDialog mFailureDialogMock; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + } + + @Test + public void testSelectCertActivityNotFound() { + doThrow(new ActivityNotFoundException()).when(mKeyChainMock).choosePrivateKeyAlias(); + + SSLClientCertificateRequest.maybeShowCertSelection( + mKeyChainMock, mCallbackMock, mFailureDialogMock); + + verify(mKeyChainMock).choosePrivateKeyAlias(); + verify(mCallbackMock).alias(null); + verify(mFailureDialogMock).show(); + } + + @Test + public void testSelectCertActivityFound() { + SSLClientCertificateRequest.maybeShowCertSelection( + mKeyChainMock, mCallbackMock, mFailureDialogMock); + + verify(mKeyChainMock).choosePrivateKeyAlias(); + verifyZeroInteractions(mFailureDialogMock); + } +} diff --git a/chromium/components/browser_ui/client_certificate/android/ssl_client_certificate_request.cc b/chromium/components/browser_ui/client_certificate/android/ssl_client_certificate_request.cc new file mode 100644 index 00000000000..13cb4583889 --- /dev/null +++ b/chromium/components/browser_ui/client_certificate/android/ssl_client_certificate_request.cc @@ -0,0 +1,394 @@ +// Copyright (c) 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 "components/browser_ui/client_certificate/android/ssl_client_certificate_request.h" + +#include <stddef.h> +#include <utility> + +#include "base/android/jni_array.h" +#include "base/android/jni_string.h" +#include "base/android/scoped_java_ref.h" +#include "base/bind.h" +#include "base/compiler_specific.h" +#include "base/containers/queue.h" +#include "base/logging.h" +#include "base/memory/ref_counted.h" +#include "components/browser_ui/client_certificate/android/jni_headers/SSLClientCertificateRequest_jni.h" +#include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/client_certificate_delegate.h" +#include "content/public/browser/navigation_handle.h" +#include "content/public/browser/web_contents_observer.h" +#include "content/public/browser/web_contents_user_data.h" +#include "net/base/host_port_pair.h" +#include "net/cert/cert_database.h" +#include "net/cert/x509_certificate.h" +#include "net/ssl/ssl_cert_request_info.h" +#include "net/ssl/ssl_client_cert_type.h" +#include "net/ssl/ssl_platform_key_android.h" +#include "net/ssl/ssl_private_key.h" +#include "ui/android/view_android.h" +#include "ui/android/window_android.h" + +namespace browser_ui { +namespace { +using base::android::JavaParamRef; +using base::android::ScopedJavaLocalRef; + +class SSLClientCertPendingRequests; + +class ClientCertRequest { + public: + ClientCertRequest( + base::WeakPtr<SSLClientCertPendingRequests> pending_requests, + const scoped_refptr<net::SSLCertRequestInfo>& cert_request_info, + std::unique_ptr<content::ClientCertificateDelegate> delegate) + : pending_requests_(pending_requests), + cert_request_info_(cert_request_info), + delegate_(std::move(delegate)) {} + + base::OnceClosure GetCancellationCallback() { + return base::BindOnce(&ClientCertRequest::OnCancel, + weak_factory_.GetWeakPtr()); + } + + void CertificateSelected(scoped_refptr<net::X509Certificate> cert, + scoped_refptr<net::SSLPrivateKey> key); + + void OnCancel(); + + net::SSLCertRequestInfo* cert_request_info() const { + return cert_request_info_.get(); + } + + private: + base::WeakPtr<SSLClientCertPendingRequests> pending_requests_; + scoped_refptr<net::SSLCertRequestInfo> cert_request_info_; + std::unique_ptr<content::ClientCertificateDelegate> delegate_; + base::WeakPtrFactory<ClientCertRequest> weak_factory_{this}; + + DISALLOW_COPY_AND_ASSIGN(ClientCertRequest); +}; + +class SSLClientCertPendingRequests + : public content::WebContentsUserData<SSLClientCertPendingRequests>, + public content::WebContentsObserver { + public: + explicit SSLClientCertPendingRequests(content::WebContents* web_contents) + : content::WebContentsObserver(web_contents) {} + ~SSLClientCertPendingRequests() override {} + + void AddRequest(std::unique_ptr<ClientCertRequest> request); + + void RequestComplete(net::SSLCertRequestInfo* info, + scoped_refptr<net::X509Certificate> cert, + scoped_refptr<net::SSLPrivateKey> key); + + // Remove pending requests when |should_keep| returns false. Calls |on_drop| + // before dropping a request. + void FilterPendingRequests( + std::function<bool(ClientCertRequest*)> should_keep, + std::function<void(ClientCertRequest*)> on_drop); + + base::WeakPtr<SSLClientCertPendingRequests> GetWeakPtr() { + return weak_factory_.GetWeakPtr(); + } + + void ReadyToCommitNavigation( + content::NavigationHandle* navigation_handle) override; + + class CertificateDialogPolicy { + public: + // Has the maximum number of cert dialogs been exceeded? + bool MaxExceeded() { return count_ >= k_max_displayed_dialogs; } + // Resets counter. Should be called on navigation. + void ResetCount() { count_ = 0; } + // Increment the counter. + void IncrementCount() { count_++; } + + private: + size_t count_ = 0; + const size_t k_max_displayed_dialogs = 5; + }; + + private: + void PumpRequests(); + + bool active_request_ = false; + + CertificateDialogPolicy dialog_policy_; + base::queue<std::unique_ptr<ClientCertRequest>> pending_requests_; + base::WeakPtrFactory<SSLClientCertPendingRequests> weak_factory_{this}; + + friend class content::WebContentsUserData<SSLClientCertPendingRequests>; + + WEB_CONTENTS_USER_DATA_KEY_DECL(); +}; + +ui::WindowAndroid* GetWindowFromWebContents( + content::WebContents* web_contents) { + ui::ViewAndroid* view = web_contents->GetNativeView(); + if (view == nullptr) { + LOG(ERROR) << "Could not get ViewAndroid"; + return nullptr; + } + // May return nullptr. + return view->GetWindowAndroid(); +} + +WEB_CONTENTS_USER_DATA_KEY_IMPL(SSLClientCertPendingRequests) + +static void StartClientCertificateRequest( + std::unique_ptr<ClientCertRequest> request, + content::WebContents* web_contents) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + ui::WindowAndroid* window = GetWindowFromWebContents(web_contents); + if (window == nullptr) { + LOG(ERROR) << "Could not get Window"; + return; + } + + // Build the |key_types| JNI parameter, as a String[] + std::vector<std::string> key_types; + for (size_t n = 0; n < request->cert_request_info()->cert_key_types.size(); + ++n) { + switch (request->cert_request_info()->cert_key_types[n]) { + case net::CLIENT_CERT_RSA_SIGN: + key_types.push_back("RSA"); + break; + case net::CLIENT_CERT_ECDSA_SIGN: + key_types.push_back("EC"); + break; + default: + // Ignore unknown types. + break; + } + } + + JNIEnv* env = base::android::AttachCurrentThread(); + ScopedJavaLocalRef<jobjectArray> key_types_ref = + base::android::ToJavaArrayOfStrings(env, key_types); + if (key_types_ref.is_null()) { + LOG(ERROR) << "Could not create key types array (String[])"; + return; + } + + // Build the |encoded_principals| JNI parameter, as a byte[][] + ScopedJavaLocalRef<jobjectArray> principals_ref = + base::android::ToJavaArrayOfByteArray( + env, request->cert_request_info()->cert_authorities); + if (principals_ref.is_null()) { + LOG(ERROR) << "Could not create principals array (byte[][])"; + return; + } + + // Build the |host_name| and |port| JNI parameters, as a String and + // a jint. + ScopedJavaLocalRef<jstring> host_name_ref = + base::android::ConvertUTF8ToJavaString( + env, request->cert_request_info()->host_and_port.host()); + + // Pass the address of the delegate through to Java. + jlong request_id = reinterpret_cast<intptr_t>(request.get()); + + if (!Java_SSLClientCertificateRequest_selectClientCertificate( + env, request_id, window->GetJavaObject(), key_types_ref, + principals_ref, host_name_ref, + request->cert_request_info()->host_and_port.port())) { + return; + } + + // Ownership was transferred to Java. + ignore_result(request.release()); +} + +void SSLClientCertPendingRequests::AddRequest( + std::unique_ptr<ClientCertRequest> request) { + pending_requests_.push(std::move(request)); + PumpRequests(); +} + +// Note that the default value for |on_drop| is a no-op. +void SSLClientCertPendingRequests::FilterPendingRequests( + std::function<bool(ClientCertRequest*)> should_keep, + std::function<void(ClientCertRequest*)> on_drop = [](auto* unused) {}) { + base::queue<std::unique_ptr<ClientCertRequest>> new_pending_requests; + while (!pending_requests_.empty()) { + std::unique_ptr<ClientCertRequest> next = + std::move(pending_requests_.front()); + pending_requests_.pop(); + if (should_keep(next.get())) { + new_pending_requests.push(std::move(next)); + } else { + on_drop(next.get()); + } + } + pending_requests_.swap(new_pending_requests); +} + +void SSLClientCertPendingRequests::RequestComplete( + net::SSLCertRequestInfo* info, + scoped_refptr<net::X509Certificate> cert, + scoped_refptr<net::SSLPrivateKey> key) { + active_request_ = false; + + // Deduplicate pending requests. Only keep pending requests whose host and + // port differ from those of the completed request. + const std::string host_and_port = info->host_and_port.ToString(); + auto should_keep = [host_and_port](ClientCertRequest* req) { + return host_and_port != req->cert_request_info()->host_and_port.ToString(); + }; + auto on_drop = [cert, key](ClientCertRequest* req) { + req->CertificateSelected(cert, key); + }; + FilterPendingRequests(should_keep, on_drop); + + PumpRequests(); +} + +void SSLClientCertPendingRequests::PumpRequests() { + if (active_request_ || pending_requests_.empty()) { + return; + } + + active_request_ = true; + std::unique_ptr<ClientCertRequest> next = + std::move(pending_requests_.front()); + pending_requests_.pop(); + + // Check if this page is allowed to show any more client cert dialogs. + if (!dialog_policy_.MaxExceeded()) { + dialog_policy_.IncrementCount(); + StartClientCertificateRequest(std::move(next), web_contents()); + } +} + +void SSLClientCertPendingRequests::ReadyToCommitNavigation( + content::NavigationHandle* navigation_handle) { + // Be careful to only reset the the client certificate dialog counter when the + // navigation is user-initiated. Note that |HasUserGesture| does not capture + // browser-initiated navigations. The negation of |IsRendererInitiated| tells + // us whether the navigation is browser-generated. + if (navigation_handle->IsInMainFrame() && + (navigation_handle->HasUserGesture() || + !navigation_handle->IsRendererInitiated())) { + // Flush any remaining dialogs before resetting the counter. + auto should_keep = [](auto* req) { return false; }; + FilterPendingRequests(should_keep); + dialog_policy_.ResetCount(); + } +} + +void ClientCertRequest::CertificateSelected( + scoped_refptr<net::X509Certificate> cert, + scoped_refptr<net::SSLPrivateKey> key) { + delegate_->ContinueWithCertificate(cert, key); + if (pending_requests_) { + pending_requests_->RequestComplete(cert_request_info(), cert, key); + } +} + +void ClientCertRequest::OnCancel() { + // When we receive an OnCancel message, we remove this ClientCertRequest from + // the queue of pending requests. + auto should_keep = [this](auto* req) { return req != this; }; + if (pending_requests_) { + pending_requests_->FilterPendingRequests(should_keep); + } +} + +} // namespace + +// Called from JNI on request completion/result. +// |env| is the current thread's JNIEnv. +// |clazz| is the SSLClientCertificateRequest JNI class reference. +// |request_id| is the id passed to +// Java_SSLClientCertificateRequest_selectClientCertificate() in Start(). +// |encoded_chain_ref| is a JNI reference to a Java array of byte arrays, +// each item holding a DER-encoded X.509 certificate. +// |private_key_ref| is the platform PrivateKey object JNI reference for +// the client certificate. +// Note: both |encoded_chain_ref| and |private_key_ref| will be NULL if +// the user didn't select a certificate. +static void JNI_SSLClientCertificateRequest_OnSystemRequestCompletion( + JNIEnv* env, + jlong request_id, + const JavaParamRef<jobjectArray>& encoded_chain_ref, + const JavaParamRef<jobject>& private_key_ref) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + // Take back ownership of the request object. + std::unique_ptr<ClientCertRequest> request( + reinterpret_cast<ClientCertRequest*>(request_id)); + + if (encoded_chain_ref == NULL || private_key_ref == NULL) { + LOG(ERROR) << "No client certificate selected"; + request->CertificateSelected(nullptr, nullptr); + return; + } + + // Convert the encoded chain to a vector of strings. + std::vector<std::string> encoded_chain_strings; + if (encoded_chain_ref) { + base::android::JavaArrayOfByteArrayToStringVector(env, encoded_chain_ref, + &encoded_chain_strings); + } + + std::vector<base::StringPiece> encoded_chain; + for (size_t n = 0; n < encoded_chain_strings.size(); ++n) + encoded_chain.push_back(encoded_chain_strings[n]); + + // Create the X509Certificate object from the encoded chain. + scoped_refptr<net::X509Certificate> client_cert( + net::X509Certificate::CreateFromDERCertChain(encoded_chain)); + if (!client_cert.get()) { + LOG(ERROR) << "Could not decode client certificate chain"; + return; + } + + // Create an SSLPrivateKey wrapper for the private key JNI reference. + scoped_refptr<net::SSLPrivateKey> private_key = + net::WrapJavaPrivateKey(client_cert.get(), private_key_ref); + if (!private_key) { + LOG(ERROR) << "Could not create OpenSSL wrapper for private key"; + return; + } + + request->CertificateSelected(std::move(client_cert), std::move(private_key)); +} + +static void NotifyClientCertificatesChanged() { + net::CertDatabase::GetInstance()->NotifyObserversCertDBChanged(); +} + +static void +JNI_SSLClientCertificateRequest_NotifyClientCertificatesChangedOnIOThread( + JNIEnv* env) { + if (content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)) { + NotifyClientCertificatesChanged(); + } else { + content::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&NotifyClientCertificatesChanged)); + } +} + +base::OnceClosure ShowSSLClientCertificateSelector( + content::WebContents* contents, + net::SSLCertRequestInfo* cert_request_info, + std::unique_ptr<content::ClientCertificateDelegate> delegate) { + SSLClientCertPendingRequests::CreateForWebContents(contents); + SSLClientCertPendingRequests* active_requests = + SSLClientCertPendingRequests::FromWebContents(contents); + + auto client_cert_request = std::make_unique<ClientCertRequest>( + active_requests->GetWeakPtr(), cert_request_info, std::move(delegate)); + base::OnceClosure cancellation_callback = + client_cert_request->GetCancellationCallback(); + active_requests->AddRequest(std::move(client_cert_request)); + return cancellation_callback; +} + +} // namespace browser_ui diff --git a/chromium/components/browser_ui/client_certificate/android/ssl_client_certificate_request.h b/chromium/components/browser_ui/client_certificate/android/ssl_client_certificate_request.h new file mode 100644 index 00000000000..1ac2090b23c --- /dev/null +++ b/chromium/components/browser_ui/client_certificate/android/ssl_client_certificate_request.h @@ -0,0 +1,32 @@ +// Copyright 2020 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 COMPONENTS_BROWSER_UI_CLIENT_CERTIFICATE_ANDROID_SSL_CLIENT_CERTIFICATE_REQUEST_H_ +#define COMPONENTS_BROWSER_UI_CLIENT_CERTIFICATE_ANDROID_SSL_CLIENT_CERTIFICATE_REQUEST_H_ + +#include <memory> + +#include "base/callback.h" + +namespace content { +class ClientCertificateDelegate; +class WebContents; +} // namespace content + +namespace net { +class SSLCertRequestInfo; +} + +namespace browser_ui { + +// Opens a SSL client certificate selection dialog. Returns a callback that will +// cancel the dialog. +base::OnceClosure ShowSSLClientCertificateSelector( + content::WebContents* contents, + net::SSLCertRequestInfo* cert_request_info, + std::unique_ptr<content::ClientCertificateDelegate> delegate); + +} // namespace browser_ui + +#endif // COMPONENTS_BROWSER_UI_CLIENT_CERTIFICATE_ANDROID_SSL_CLIENT_CERTIFICATE_REQUEST_H_ diff --git a/chromium/components/browser_ui/http_auth/android/BUILD.gn b/chromium/components/browser_ui/http_auth/android/BUILD.gn new file mode 100644 index 00000000000..0184556b59c --- /dev/null +++ b/chromium/components/browser_ui/http_auth/android/BUILD.gn @@ -0,0 +1,33 @@ +# Copyright 2020 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. + +import("//build/config/android/rules.gni") + +android_library("java") { + sources = [ + "java/src/org/chromium/components/browser_ui/http_auth/LoginPrompt.java", + ] + + deps = [ + ":java_resources", + "//base:base_java", + "//components/browser_ui/widget/android:java", + "//components/strings:components_strings_grd", + "//third_party/android_deps:androidx_appcompat_appcompat_java", + "//third_party/android_deps:com_google_android_material_material_java", + "//ui/android:ui_java", + ] +} + +android_resources("java_resources") { + custom_package = "org.chromium.components.browser_ui.http_auth" + sources = [ "java/res/layout/http_auth_dialog.xml" ] + + deps = [ + "//components/browser_ui/styles/android:java_resources", + "//components/browser_ui/widget/android:java_resources", + "//components/strings:components_strings_grd", + "//ui/android:ui_java_resources", + ] +} diff --git a/chromium/components/browser_ui/http_auth/android/DEPS b/chromium/components/browser_ui/http_auth/android/DEPS new file mode 100644 index 00000000000..d21e0729f9c --- /dev/null +++ b/chromium/components/browser_ui/http_auth/android/DEPS @@ -0,0 +1,3 @@ +include_rules = [ + "+ui/android", +] diff --git a/chromium/components/browser_ui/http_auth/android/OWNERS b/chromium/components/browser_ui/http_auth/android/OWNERS new file mode 100644 index 00000000000..697c69edec7 --- /dev/null +++ b/chromium/components/browser_ui/http_auth/android/OWNERS @@ -0,0 +1 @@ +file://chrome/android/OWNERS diff --git a/chromium/components/browser_ui/http_auth/android/java/res/OWNERS b/chromium/components/browser_ui/http_auth/android/java/res/OWNERS new file mode 100644 index 00000000000..7bb5d6933c5 --- /dev/null +++ b/chromium/components/browser_ui/http_auth/android/java/res/OWNERS @@ -0,0 +1,9 @@ +# This restriction is in place to avoid accidential addition to our top level +# layout files, such as add duplicated assets, or introducing new colors when +# we don't want them. +set noparent + +file://ui/android/java/res/LAYOUT_OWNERS + +# COMPONENT: UI>Browser>Mobile +# OS: Android diff --git a/chromium/components/browser_ui/http_auth/android/java/res/layout/http_auth_dialog.xml b/chromium/components/browser_ui/http_auth/android/java/res/layout/http_auth_dialog.xml new file mode 100644 index 00000000000..f55df1e32a5 --- /dev/null +++ b/chromium/components/browser_ui/http_auth/android/java/res/layout/http_auth_dialog.xml @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2014 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. +--> +<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" + style="@style/AlertDialogContent"> + + <LinearLayout + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <TextView + android:id="@+id/explanation" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + + <com.google.android.material.textfield.TextInputLayout + android:id="@+id/username_label" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:hint="@string/login_dialog_username_field" > + <org.chromium.components.browser_ui.widget.text.AlertDialogEditText + android:id="@+id/username" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:hint="@string/login_dialog_username_field" + android:inputType="textNoSuggestions" + android:imeOptions="flagNoExtractUi" + android:importantForAutofill="no" /> + </com.google.android.material.textfield.TextInputLayout> + + <com.google.android.material.textfield.TextInputLayout + android:id="@+id/password_label" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:hint="@string/login_dialog_password_field" > + <org.chromium.components.browser_ui.widget.text.AlertDialogEditText + android:id="@+id/password" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:hint="@string/login_dialog_password_field" + android:inputType="textPassword" + android:imeOptions="flagNoExtractUi" + android:importantForAutofill="no" /> + </com.google.android.material.textfield.TextInputLayout> + + </LinearLayout> + +</ScrollView> diff --git a/chromium/components/browser_ui/http_auth/android/java/src/org/chromium/components/browser_ui/http_auth/LoginPrompt.java b/chromium/components/browser_ui/http_auth/android/java/src/org/chromium/components/browser_ui/http_auth/LoginPrompt.java new file mode 100644 index 00000000000..a97b221d24d --- /dev/null +++ b/chromium/components/browser_ui/http_auth/android/java/src/org/chromium/components/browser_ui/http_auth/LoginPrompt.java @@ -0,0 +1,142 @@ +// Copyright 2014 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.components.browser_ui.http_auth; + +import android.content.Context; +import android.content.DialogInterface; +import android.os.Build; +import android.view.LayoutInflater; +import android.view.View; +import android.view.WindowManager; +import android.view.inputmethod.EditorInfo; +import android.widget.TextView; + +import androidx.appcompat.app.AlertDialog; + +import org.chromium.components.browser_ui.widget.text.AlertDialogEditText; +import org.chromium.ui.UiUtils; + +/** + * HTTP Authentication Dialog + * + * This borrows liberally from android.browser.HttpAuthenticationDialog. + */ +public class LoginPrompt { + private final Context mContext; + private final String mMessageBody; + private final Observer mObserver; + + private AlertDialog mDialog; + private AlertDialogEditText mUsernameView; + private AlertDialogEditText mPasswordView; + + /** + * This is a public interface that provides the result of the prompt. + */ + public static interface Observer { + /** + * Cancel the authorization request. + */ + public void cancel(); + + /** + * Proceed with the authorization with the given credentials. + */ + public void proceed(String username, String password); + } + + /** + * Constructs an http auth prompt. + * + * @param context The Context to use. + * @param messageBody The text to show to the user. + * @param autofillUrl If not null, Android Autofill support is enabled for the form with the + * given url being set as the web domain for the View control. + * @param observer An interface to receive the result of the prompt. + */ + public LoginPrompt(Context context, String messageBody, String autofillUrl, Observer observer) { + mContext = context; + mMessageBody = messageBody; + mObserver = observer; + createDialog(autofillUrl); + } + + private void createDialog(String autofillUrl) { + View v = LayoutInflater.from(mContext).inflate(R.layout.http_auth_dialog, null); + mUsernameView = (AlertDialogEditText) v.findViewById(R.id.username); + mPasswordView = (AlertDialogEditText) v.findViewById(R.id.password); + if (autofillUrl != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + // By default Android Autofill support is turned off for these controls because Chrome + // uses its own autofill provider (Chrome Sync). If an app is using Android Autofill + // then we need to enable Android Autofill for the controls. + mUsernameView.setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_YES); + mPasswordView.setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_YES); + mUsernameView.setUrl(autofillUrl); + mPasswordView.setUrl(autofillUrl); + } + mPasswordView.setOnEditorActionListener((v1, actionId, event) -> { + if (actionId == EditorInfo.IME_ACTION_DONE) { + mDialog.getButton(AlertDialog.BUTTON_POSITIVE).performClick(); + return true; + } + return false; + }); + + TextView explanationView = (TextView) v.findViewById(R.id.explanation); + explanationView.setText(mMessageBody); + + mDialog = + new UiUtils + .CompatibleAlertDialogBuilder(mContext, R.style.Theme_Chromium_AlertDialog) + .setTitle(R.string.login_dialog_title) + .setView(v) + .setPositiveButton(R.string.login_dialog_ok_button_label, + (DialogInterface.OnClickListener) (dialog, whichButton) + -> mObserver.proceed(getUsername(), getPassword())) + .setNegativeButton(R.string.cancel, + (DialogInterface.OnClickListener) (dialog, + whichButton) -> mObserver.cancel()) + .setOnCancelListener(dialog -> mObserver.cancel()) + .create(); + mDialog.getDelegate().setHandleNativeActionModesEnabled(false); + + // Make the IME appear when the dialog is displayed if applicable. + mDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); + } + + /** + * Shows the dialog. + */ + public void show() { + mDialog.show(); + mUsernameView.requestFocus(); + } + + /** + * Dismisses the dialog. + */ + public void dismiss() { + mDialog.dismiss(); + } + + /** Return whether the dialog is being shown. */ + public boolean isShowing() { + return mDialog != null && mDialog.isShowing(); + } + + private String getUsername() { + return mUsernameView.getText().toString(); + } + + private String getPassword() { + return mPasswordView.getText().toString(); + } + + public void onAutofillDataAvailable(String username, String password) { + mUsernameView.setText(username); + mPasswordView.setText(password); + mUsernameView.selectAll(); + } +} diff --git a/chromium/components/browser_ui/media/OWNERS b/chromium/components/browser_ui/media/OWNERS new file mode 100644 index 00000000000..28f64e589e9 --- /dev/null +++ b/chromium/components/browser_ui/media/OWNERS @@ -0,0 +1,4 @@ +mlamouri@chromium.org + +# TEAM: media-dev@chromium.org +# COMPONENT: Internals>Media>UI diff --git a/chromium/components/browser_ui/media/android/BUILD.gn b/chromium/components/browser_ui/media/android/BUILD.gn new file mode 100644 index 00000000000..31b7a047305 --- /dev/null +++ b/chromium/components/browser_ui/media/android/BUILD.gn @@ -0,0 +1,95 @@ +# Copyright 2020 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. + +import("//build/config/android/rules.gni") + +android_library("java") { + sources = [ + "java/src/org/chromium/components/browser_ui/media/MediaImageCallback.java", + "java/src/org/chromium/components/browser_ui/media/MediaImageManager.java", + "java/src/org/chromium/components/browser_ui/media/MediaNotificationController.java", + "java/src/org/chromium/components/browser_ui/media/MediaNotificationImageUtils.java", + "java/src/org/chromium/components/browser_ui/media/MediaNotificationInfo.java", + "java/src/org/chromium/components/browser_ui/media/MediaNotificationListener.java", + "java/src/org/chromium/components/browser_ui/media/MediaNotificationUma.java", + "java/src/org/chromium/components/browser_ui/media/MediaSessionHelper.java", + "java/src/org/chromium/components/browser_ui/media/MediaSessionUma.java", + ] + + deps = [ + ":java_resources", + "//base:base_java", + "//components/browser_ui/notifications/android:java", + "//components/url_formatter/android:url_formatter_java", + "//content/public/android:content_java", + "//services/media_session/public/cpp/android:media_session_java", + "//services/media_session/public/mojom:mojom_java", + "//third_party/android_deps:android_support_v4_java", + "//ui/android:ui_full_java", + "//url:gurl_java", + ] +} + +android_resources("java_resources") { + custom_package = "org.chromium.components.browser_ui.media" + sources = [ + "java/res/drawable-hdpi/audio_playing.png", + "java/res/drawable-hdpi/audio_playing_square.png", + "java/res/drawable-hdpi/ic_fast_forward_white_36dp.png", + "java/res/drawable-hdpi/ic_fast_rewind_white_36dp.png", + "java/res/drawable-hdpi/ic_skip_next_white_36dp.png", + "java/res/drawable-hdpi/ic_skip_previous_white_36dp.png", + "java/res/drawable-mdpi/audio_playing.png", + "java/res/drawable-mdpi/audio_playing_square.png", + "java/res/drawable-mdpi/ic_fast_forward_white_36dp.png", + "java/res/drawable-mdpi/ic_fast_rewind_white_36dp.png", + "java/res/drawable-mdpi/ic_skip_next_white_36dp.png", + "java/res/drawable-mdpi/ic_skip_previous_white_36dp.png", + "java/res/drawable-xhdpi/audio_playing.png", + "java/res/drawable-xhdpi/audio_playing_square.png", + "java/res/drawable-xhdpi/ic_fast_forward_white_36dp.png", + "java/res/drawable-xhdpi/ic_fast_rewind_white_36dp.png", + "java/res/drawable-xhdpi/ic_skip_next_white_36dp.png", + "java/res/drawable-xhdpi/ic_skip_previous_white_36dp.png", + "java/res/drawable-xxhdpi/audio_playing.png", + "java/res/drawable-xxhdpi/audio_playing_square.png", + "java/res/drawable-xxhdpi/ic_fast_forward_white_36dp.png", + "java/res/drawable-xxhdpi/ic_fast_rewind_white_36dp.png", + "java/res/drawable-xxhdpi/ic_skip_next_white_36dp.png", + "java/res/drawable-xxhdpi/ic_skip_previous_white_36dp.png", + "java/res/drawable-xxxhdpi/audio_playing.png", + "java/res/drawable-xxxhdpi/audio_playing_square.png", + "java/res/drawable-xxxhdpi/ic_fast_forward_white_36dp.png", + "java/res/drawable-xxxhdpi/ic_fast_rewind_white_36dp.png", + "java/res/drawable-xxxhdpi/ic_skip_next_white_36dp.png", + "java/res/drawable-xxxhdpi/ic_skip_previous_white_36dp.png", + ] + deps = [ + "//components/browser_ui/strings/android:browser_ui_strings_grd", + "//components/browser_ui/styles/android:java_resources", + ] +} + +java_library("junit") { + # Skip platform checks since Robolectric depends on requires_android targets. + bypass_platform_checks = true + testonly = true + sources = [ + "java/src/org/chromium/components/browser_ui/media/MediaImageManagerTest.java", + "java/src/org/chromium/components/browser_ui/media/MediaNotificationButtonComputationTest.java", + ] + deps = [ + ":java", + "//base:base_java", + "//base:base_java_test_support", + "//base:base_junit_test_support", + "//base/test:test_support_java", + "//content/public/android:content_java", + "//services/media_session/public/cpp/android:media_session_java", + "//services/media_session/public/mojom:mojom_java", + "//third_party/android_deps:robolectric_all_java", + "//third_party/junit", + "//third_party/mockito:mockito_java", + ] +} diff --git a/chromium/components/browser_ui/media/android/DEPS b/chromium/components/browser_ui/media/android/DEPS new file mode 100644 index 00000000000..652050725b0 --- /dev/null +++ b/chromium/components/browser_ui/media/android/DEPS @@ -0,0 +1,6 @@ +include_rules = [ + "+components/url_formatter/android", + "+content/public/android", + "+services/media_session/public/cpp/android", + "+ui/android", +] diff --git a/chromium/components/browser_ui/media/android/java/res/drawable-hdpi/audio_playing.png b/chromium/components/browser_ui/media/android/java/res/drawable-hdpi/audio_playing.png Binary files differnew file mode 100644 index 00000000000..75d13258a70 --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/res/drawable-hdpi/audio_playing.png diff --git a/chromium/components/browser_ui/media/android/java/res/drawable-hdpi/audio_playing_square.png b/chromium/components/browser_ui/media/android/java/res/drawable-hdpi/audio_playing_square.png Binary files differnew file mode 100644 index 00000000000..94108427da0 --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/res/drawable-hdpi/audio_playing_square.png diff --git a/chromium/components/browser_ui/media/android/java/res/drawable-hdpi/ic_fast_forward_white_36dp.png b/chromium/components/browser_ui/media/android/java/res/drawable-hdpi/ic_fast_forward_white_36dp.png Binary files differnew file mode 100644 index 00000000000..6a7db4b8c80 --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/res/drawable-hdpi/ic_fast_forward_white_36dp.png diff --git a/chromium/components/browser_ui/media/android/java/res/drawable-hdpi/ic_fast_rewind_white_36dp.png b/chromium/components/browser_ui/media/android/java/res/drawable-hdpi/ic_fast_rewind_white_36dp.png Binary files differnew file mode 100644 index 00000000000..656d0220963 --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/res/drawable-hdpi/ic_fast_rewind_white_36dp.png diff --git a/chromium/components/browser_ui/media/android/java/res/drawable-hdpi/ic_skip_next_white_36dp.png b/chromium/components/browser_ui/media/android/java/res/drawable-hdpi/ic_skip_next_white_36dp.png Binary files differnew file mode 100644 index 00000000000..cf68df833a9 --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/res/drawable-hdpi/ic_skip_next_white_36dp.png diff --git a/chromium/components/browser_ui/media/android/java/res/drawable-hdpi/ic_skip_previous_white_36dp.png b/chromium/components/browser_ui/media/android/java/res/drawable-hdpi/ic_skip_previous_white_36dp.png Binary files differnew file mode 100644 index 00000000000..da1c1c958f2 --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/res/drawable-hdpi/ic_skip_previous_white_36dp.png diff --git a/chromium/components/browser_ui/media/android/java/res/drawable-mdpi/audio_playing.png b/chromium/components/browser_ui/media/android/java/res/drawable-mdpi/audio_playing.png Binary files differnew file mode 100644 index 00000000000..a9ccbc15101 --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/res/drawable-mdpi/audio_playing.png diff --git a/chromium/components/browser_ui/media/android/java/res/drawable-mdpi/audio_playing_square.png b/chromium/components/browser_ui/media/android/java/res/drawable-mdpi/audio_playing_square.png Binary files differnew file mode 100644 index 00000000000..acbe6dbea23 --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/res/drawable-mdpi/audio_playing_square.png diff --git a/chromium/components/browser_ui/media/android/java/res/drawable-mdpi/ic_fast_forward_white_36dp.png b/chromium/components/browser_ui/media/android/java/res/drawable-mdpi/ic_fast_forward_white_36dp.png Binary files differnew file mode 100644 index 00000000000..f890f113715 --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/res/drawable-mdpi/ic_fast_forward_white_36dp.png diff --git a/chromium/components/browser_ui/media/android/java/res/drawable-mdpi/ic_fast_rewind_white_36dp.png b/chromium/components/browser_ui/media/android/java/res/drawable-mdpi/ic_fast_rewind_white_36dp.png Binary files differnew file mode 100644 index 00000000000..9d02d436605 --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/res/drawable-mdpi/ic_fast_rewind_white_36dp.png diff --git a/chromium/components/browser_ui/media/android/java/res/drawable-mdpi/ic_skip_next_white_36dp.png b/chromium/components/browser_ui/media/android/java/res/drawable-mdpi/ic_skip_next_white_36dp.png Binary files differnew file mode 100644 index 00000000000..9032328d4df --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/res/drawable-mdpi/ic_skip_next_white_36dp.png diff --git a/chromium/components/browser_ui/media/android/java/res/drawable-mdpi/ic_skip_previous_white_36dp.png b/chromium/components/browser_ui/media/android/java/res/drawable-mdpi/ic_skip_previous_white_36dp.png Binary files differnew file mode 100644 index 00000000000..23faeeb0264 --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/res/drawable-mdpi/ic_skip_previous_white_36dp.png diff --git a/chromium/components/browser_ui/media/android/java/res/drawable-xhdpi/audio_playing.png b/chromium/components/browser_ui/media/android/java/res/drawable-xhdpi/audio_playing.png Binary files differnew file mode 100644 index 00000000000..7fcb219818e --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/res/drawable-xhdpi/audio_playing.png diff --git a/chromium/components/browser_ui/media/android/java/res/drawable-xhdpi/audio_playing_square.png b/chromium/components/browser_ui/media/android/java/res/drawable-xhdpi/audio_playing_square.png Binary files differnew file mode 100644 index 00000000000..212aa900ffb --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/res/drawable-xhdpi/audio_playing_square.png diff --git a/chromium/components/browser_ui/media/android/java/res/drawable-xhdpi/ic_fast_forward_white_36dp.png b/chromium/components/browser_ui/media/android/java/res/drawable-xhdpi/ic_fast_forward_white_36dp.png Binary files differnew file mode 100644 index 00000000000..f7d810f1248 --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/res/drawable-xhdpi/ic_fast_forward_white_36dp.png diff --git a/chromium/components/browser_ui/media/android/java/res/drawable-xhdpi/ic_fast_rewind_white_36dp.png b/chromium/components/browser_ui/media/android/java/res/drawable-xhdpi/ic_fast_rewind_white_36dp.png Binary files differnew file mode 100644 index 00000000000..12ff39ab480 --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/res/drawable-xhdpi/ic_fast_rewind_white_36dp.png diff --git a/chromium/components/browser_ui/media/android/java/res/drawable-xhdpi/ic_skip_next_white_36dp.png b/chromium/components/browser_ui/media/android/java/res/drawable-xhdpi/ic_skip_next_white_36dp.png Binary files differnew file mode 100644 index 00000000000..972192d3937 --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/res/drawable-xhdpi/ic_skip_next_white_36dp.png diff --git a/chromium/components/browser_ui/media/android/java/res/drawable-xhdpi/ic_skip_previous_white_36dp.png b/chromium/components/browser_ui/media/android/java/res/drawable-xhdpi/ic_skip_previous_white_36dp.png Binary files differnew file mode 100644 index 00000000000..1181ec926a8 --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/res/drawable-xhdpi/ic_skip_previous_white_36dp.png diff --git a/chromium/components/browser_ui/media/android/java/res/drawable-xxhdpi/audio_playing.png b/chromium/components/browser_ui/media/android/java/res/drawable-xxhdpi/audio_playing.png Binary files differnew file mode 100644 index 00000000000..a743b72ac6b --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/res/drawable-xxhdpi/audio_playing.png diff --git a/chromium/components/browser_ui/media/android/java/res/drawable-xxhdpi/audio_playing_square.png b/chromium/components/browser_ui/media/android/java/res/drawable-xxhdpi/audio_playing_square.png Binary files differnew file mode 100644 index 00000000000..403f6945051 --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/res/drawable-xxhdpi/audio_playing_square.png diff --git a/chromium/components/browser_ui/media/android/java/res/drawable-xxhdpi/ic_fast_forward_white_36dp.png b/chromium/components/browser_ui/media/android/java/res/drawable-xxhdpi/ic_fast_forward_white_36dp.png Binary files differnew file mode 100644 index 00000000000..b41b3de40b6 --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/res/drawable-xxhdpi/ic_fast_forward_white_36dp.png diff --git a/chromium/components/browser_ui/media/android/java/res/drawable-xxhdpi/ic_fast_rewind_white_36dp.png b/chromium/components/browser_ui/media/android/java/res/drawable-xxhdpi/ic_fast_rewind_white_36dp.png Binary files differnew file mode 100644 index 00000000000..253833bbc36 --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/res/drawable-xxhdpi/ic_fast_rewind_white_36dp.png diff --git a/chromium/components/browser_ui/media/android/java/res/drawable-xxhdpi/ic_skip_next_white_36dp.png b/chromium/components/browser_ui/media/android/java/res/drawable-xxhdpi/ic_skip_next_white_36dp.png Binary files differnew file mode 100644 index 00000000000..4652215ccc8 --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/res/drawable-xxhdpi/ic_skip_next_white_36dp.png diff --git a/chromium/components/browser_ui/media/android/java/res/drawable-xxhdpi/ic_skip_previous_white_36dp.png b/chromium/components/browser_ui/media/android/java/res/drawable-xxhdpi/ic_skip_previous_white_36dp.png Binary files differnew file mode 100644 index 00000000000..c8db47f6635 --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/res/drawable-xxhdpi/ic_skip_previous_white_36dp.png diff --git a/chromium/components/browser_ui/media/android/java/res/drawable-xxxhdpi/audio_playing.png b/chromium/components/browser_ui/media/android/java/res/drawable-xxxhdpi/audio_playing.png Binary files differnew file mode 100644 index 00000000000..5139cbdba20 --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/res/drawable-xxxhdpi/audio_playing.png diff --git a/chromium/components/browser_ui/media/android/java/res/drawable-xxxhdpi/audio_playing_square.png b/chromium/components/browser_ui/media/android/java/res/drawable-xxxhdpi/audio_playing_square.png Binary files differnew file mode 100644 index 00000000000..e994ee339dd --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/res/drawable-xxxhdpi/audio_playing_square.png diff --git a/chromium/components/browser_ui/media/android/java/res/drawable-xxxhdpi/ic_fast_forward_white_36dp.png b/chromium/components/browser_ui/media/android/java/res/drawable-xxxhdpi/ic_fast_forward_white_36dp.png Binary files differnew file mode 100644 index 00000000000..b111f7d2541 --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/res/drawable-xxxhdpi/ic_fast_forward_white_36dp.png diff --git a/chromium/components/browser_ui/media/android/java/res/drawable-xxxhdpi/ic_fast_rewind_white_36dp.png b/chromium/components/browser_ui/media/android/java/res/drawable-xxxhdpi/ic_fast_rewind_white_36dp.png Binary files differnew file mode 100644 index 00000000000..e1baaa33127 --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/res/drawable-xxxhdpi/ic_fast_rewind_white_36dp.png diff --git a/chromium/components/browser_ui/media/android/java/res/drawable-xxxhdpi/ic_skip_next_white_36dp.png b/chromium/components/browser_ui/media/android/java/res/drawable-xxxhdpi/ic_skip_next_white_36dp.png Binary files differnew file mode 100644 index 00000000000..00b29dd1703 --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/res/drawable-xxxhdpi/ic_skip_next_white_36dp.png diff --git a/chromium/components/browser_ui/media/android/java/res/drawable-xxxhdpi/ic_skip_previous_white_36dp.png b/chromium/components/browser_ui/media/android/java/res/drawable-xxxhdpi/ic_skip_previous_white_36dp.png Binary files differnew file mode 100644 index 00000000000..9e52d5001ea --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/res/drawable-xxxhdpi/ic_skip_previous_white_36dp.png diff --git a/chromium/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaImageCallback.java b/chromium/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaImageCallback.java new file mode 100644 index 00000000000..117373ad0ef --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaImageCallback.java @@ -0,0 +1,22 @@ +// Copyright 2016 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.components.browser_ui.media; + +import android.graphics.Bitmap; + +import androidx.annotation.Nullable; + +/** + * The callback when an image is downloaded. This class is different with + * {@link ImageDownloadCallback} and is only used by {@link MediaImageManager}. + */ +public interface MediaImageCallback { + /** + * Called when image downloading is complete. + * @param bitmap The downloaded image. |null| indicates there is no available src for download + * or image download failed. + */ + void onImageDownloaded(@Nullable Bitmap image); +} diff --git a/chromium/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaImageManager.java b/chromium/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaImageManager.java new file mode 100644 index 00000000000..b2fa480fe90 --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaImageManager.java @@ -0,0 +1,235 @@ +// Copyright 2016 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.components.browser_ui.media; + +import android.graphics.Bitmap; +import android.graphics.Rect; +import android.text.TextUtils; + +import androidx.annotation.VisibleForTesting; + +import org.chromium.base.FileUtils; +import org.chromium.content_public.browser.ImageDownloadCallback; +import org.chromium.content_public.browser.WebContents; +import org.chromium.services.media_session.MediaImage; + +import java.util.Iterator; +import java.util.List; + +/** + * A class for managing the MediaImage download process. + * + * The manager takes a list of {@link MediaMetadata.MediaImage} as input, and + * selects one of them based on scoring and start download through + * {@link WebContents} asynchronously. When the download successfully finishes, + * the manager runs the callback function to notify the completion and pass the + * downloaded Bitmap. + * + * The scoring works as follows: + * - A image score is computed by multiplying the type score with the size score. + * - The type score lies in [0, 1] and is based on the image MIME type/file extension. + * - PNG and JPEG are prefered than others. + * - If unspecified, use the default type score (0.6). + * - The size score lies in [0, 1] and is computed by multiplying the dominant size score and aspect + * ratio score: + * - The dominant size score lies in [0, 1] and is computed using |mMinimumSize| and |mIdealSize|: + * - If size < |mMinimumSize| (too small), the size score is 0. + * - If |mMinimumSize| <= size <= |mIdealSize|, the score increases linearly from 0.2 to 1. + * - If size > |mIdealSize|, the score is |mIdealSize| / size, which drops from 1 to 0. + * - When the size is "any", the size score is 0.8. + * - If unspecified, use the default size score (0.4). + * - The aspect ratio score lies in [0, 1] and is computed by dividing the short edge length by + * the long edge. + */ +public class MediaImageManager implements ImageDownloadCallback { + // The default score of unknown image size. + private static final double DEFAULT_IMAGE_SIZE_SCORE = 0.4; + // The scores for different image types. Keep them sorted by value. + private static final double TYPE_SCORE_DEFAULT = 0.6; + private static final double TYPE_SCORE_PNG = 1.0; + private static final double TYPE_SCORE_JPEG = 0.7; + private static final double TYPE_SCORE_BMP = 0.5; + private static final double TYPE_SCORE_XICON = 0.4; + private static final double TYPE_SCORE_GIF = 0.3; + + @VisibleForTesting + static final int MAX_BITMAP_SIZE_FOR_DOWNLOAD = 2048; + + private WebContents mWebContents; + // The minimum image size. Images that are smaller than |mMinimumSize| will be ignored. + final int mMinimumSize; + // The ideal image size. Images that are too large than |mIdealSize| will be ignored. + final int mIdealSize; + // The pending download image request id, which is set when calling + // {@link WebContents#downloadImage()}, and reset when image download completes or + // {@link #clearRequests()} is called. + private int mRequestId; + // The callback to be called when the pending download image request completes. + private MediaImageCallback mCallback; + + // The last image src for download, used for avoiding fetching the same src when artwork is set + // multiple times but the same src is chosen. + // + // Will be reset when initiating a new download request. + private String mLastImageSrc; + + /** + * MediaImageManager constructor. + * @param minimumSize The minimum size of images to download. + * @param idealSize The ideal size of images to download. + */ + public MediaImageManager(int minimumSize, int idealSize) { + mMinimumSize = minimumSize; + mIdealSize = idealSize; + clearRequests(); + } + + /** + * Called when the WebContent changes. + * @param contents The new WebContents. + */ + public void setWebContents(WebContents contents) { + mWebContents = contents; + clearRequests(); + } + + /** + * Select the best image from |images| and start download. + * @param images The list of images to choose from. Null is equivalent to empty list. + * @param callback The callback when image download completes. + */ + public void downloadImage(List<MediaImage> images, MediaImageCallback callback) { + if (mWebContents == null) return; + + mCallback = callback; + MediaImage image = selectImage(images); + if (image == null) { + mLastImageSrc = null; + mCallback.onImageDownloaded(null); + clearRequests(); + return; + } + + // Avoid fetching the same image twice. + if (TextUtils.equals(image.getSrc(), mLastImageSrc)) return; + mLastImageSrc = image.getSrc(); + + // Limit |maxBitmapSize| to |MAX_BITMAP_SIZE_FOR_DOWNLOAD| to avoid passing huge bitmaps + // through JNI. |maxBitmapSize| does not prevent huge images to be downloaded. It is used to + // filter/rescale the download images. See documentation of + // {@link WebContents#downloadImage()} for details. + mRequestId = mWebContents.downloadImage(image.getSrc(), // url + false, // isFavicon + MAX_BITMAP_SIZE_FOR_DOWNLOAD, // maxBitmapSize + false, // bypassCache + this); // callback + } + + /** + * ImageDownloadCallback implementation. This method is called when an download image request is + * completed. The class will only keep the latest request. If some call to this method is + * corresponding to a previous request, it will be ignored. + */ + @Override + public void onFinishDownloadImage(int id, int httpStatusCode, String imageUrl, + List<Bitmap> bitmaps, List<Rect> originalImageSizes) { + if (id != mRequestId) return; + + Iterator<Bitmap> iterBitmap = bitmaps.iterator(); + Iterator<Rect> iterSize = originalImageSizes.iterator(); + + Bitmap bestBitmap = null; + double bestScore = 0; + while (iterBitmap.hasNext() && iterSize.hasNext()) { + Bitmap bitmap = iterBitmap.next(); + Rect size = iterSize.next(); + double newScore = getImageSizeScore(size); + if (bestScore < newScore) { + bestBitmap = bitmap; + bestScore = newScore; + } + } + mCallback.onImageDownloaded(bestBitmap); + clearRequests(); + } + + /** + * Select the best image from the |images|. + * @param images The list of images to select from. Null is equivalent to empty list. + */ + private MediaImage selectImage(List<MediaImage> images) { + if (images == null) return null; + + MediaImage selectedImage = null; + double bestScore = 0; + for (MediaImage image : images) { + double newScore = getImageScore(image); + if (newScore > bestScore) { + bestScore = newScore; + selectedImage = image; + } + } + return selectedImage; + } + + private void clearRequests() { + mRequestId = -1; + mCallback = null; + } + + private double getImageScore(MediaImage image) { + if (image == null) return 0; + if (image.getSizes().isEmpty()) return DEFAULT_IMAGE_SIZE_SCORE; + + double bestSizeScore = 0; + for (Rect size : image.getSizes()) { + bestSizeScore = Math.max(bestSizeScore, getImageSizeScore(size)); + } + double typeScore = getImageTypeScore(image.getSrc(), image.getType()); + return bestSizeScore * typeScore; + } + + private double getImageSizeScore(Rect size) { + return getImageDominantSizeScore(size.width(), size.height()) + * getImageAspectRatioScore(size.width(), size.height()); + } + + private double getImageDominantSizeScore(int width, int height) { + int dominantSize = Math.max(width, height); + // When the size is "any". + if (dominantSize == 0) return 0.8; + // Ignore images that are too small. + if (dominantSize < mMinimumSize) return 0; + + if (dominantSize <= mIdealSize) { + return 0.8 * (dominantSize - mMinimumSize) / (mIdealSize - mMinimumSize) + 0.2; + } + return 1.0 * mIdealSize / dominantSize; + } + + private double getImageAspectRatioScore(int width, int height) { + double longEdge = Math.max(width, height); + double shortEdge = Math.min(width, height); + return shortEdge / longEdge; + } + + private double getImageTypeScore(String url, String type) { + String extension = FileUtils.getExtension(url); + + if ("bmp".equals(extension) || "image/bmp".equals(type)) { + return TYPE_SCORE_BMP; + } else if ("gif".equals(extension) || "image/gif".equals(type)) { + return TYPE_SCORE_GIF; + } else if ("icon".equals(extension) || "image/x-icon".equals(type)) { + return TYPE_SCORE_XICON; + } else if ("png".equals(extension) || "image/png".equals(type)) { + return TYPE_SCORE_PNG; + } else if ("jpeg".equals(extension) || "jpg".equals(extension) + || "image/jpeg".equals(type)) { + return TYPE_SCORE_JPEG; + } + return TYPE_SCORE_DEFAULT; + } +} diff --git a/chromium/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaImageManagerTest.java b/chromium/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaImageManagerTest.java new file mode 100644 index 00000000000..c45340a77e9 --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaImageManagerTest.java @@ -0,0 +1,298 @@ +// Copyright 2017 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.components.browser_ui.media; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.isNotNull; +import static org.mockito.ArgumentMatchers.isNull; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import android.graphics.Bitmap; +import android.graphics.Rect; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowLog; + +import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.content_public.browser.WebContents; +import org.chromium.services.media_session.MediaImage; + +import java.util.ArrayList; + +/** + * Robolectric tests for MediaImageManager. + */ +@RunWith(BaseRobolectricTestRunner.class) +@Config(manifest = Config.NONE) +public class MediaImageManagerTest { + private static final int TINY_IMAGE_SIZE_PX = 50; + private static final int MIN_IMAGE_SIZE_PX = 100; + private static final int IDEAL_IMAGE_SIZE_PX = 200; + private static final int REQUEST_ID_1 = 1; + private static final int REQUEST_ID_2 = 2; + private static final String IMAGE_URL_1 = "http://example.com/foo.png"; + private static final String IMAGE_URL_2 = "http://example.com/bar.png"; + + @Mock + private WebContents mWebContents; + @Mock + private MediaImageCallback mCallback; + + private MediaImageManager mMediaImageManager; + + // Prepared data for feeding. + private ArrayList<MediaImage> mImages; + private ArrayList<Bitmap> mBitmaps; + private ArrayList<Rect> mOriginalImageSizes; + + @Before + public void setUp() { + ShadowLog.stream = System.out; + MockitoAnnotations.initMocks(this); + doReturn(REQUEST_ID_1) + .when(mWebContents) + .downloadImage(anyString(), anyBoolean(), anyInt(), anyBoolean(), + any(MediaImageManager.class)); + mMediaImageManager = new MediaImageManager(MIN_IMAGE_SIZE_PX, IDEAL_IMAGE_SIZE_PX); + mMediaImageManager.setWebContents(mWebContents); + + mImages = new ArrayList<MediaImage>(); + mImages.add(new MediaImage(IMAGE_URL_1, "", new ArrayList<Rect>())); + + mBitmaps = new ArrayList<Bitmap>(); + mBitmaps.add(Bitmap.createBitmap( + IDEAL_IMAGE_SIZE_PX, IDEAL_IMAGE_SIZE_PX, Bitmap.Config.ARGB_8888)); + + mOriginalImageSizes = new ArrayList<Rect>(); + mOriginalImageSizes.add(new Rect(0, 0, IDEAL_IMAGE_SIZE_PX, IDEAL_IMAGE_SIZE_PX)); + } + + @Test + public void testDownloadImage() { + mMediaImageManager.downloadImage(mImages, mCallback); + verify(mWebContents) + .downloadImage(eq(IMAGE_URL_1), eq(false), + eq(MediaImageManager.MAX_BITMAP_SIZE_FOR_DOWNLOAD), eq(false), + eq(mMediaImageManager)); + mMediaImageManager.onFinishDownloadImage( + REQUEST_ID_1, 200, IMAGE_URL_1, mBitmaps, mOriginalImageSizes); + + verify(mCallback).onImageDownloaded((Bitmap) isNotNull()); + verify(mCallback, times(0)).onImageDownloaded((Bitmap) isNull()); + } + + @Test + public void testDownloadSameImageTwice() { + // First download. + mMediaImageManager.downloadImage(mImages, mCallback); + mMediaImageManager.onFinishDownloadImage( + REQUEST_ID_1, 200, IMAGE_URL_1, mBitmaps, mOriginalImageSizes); + + // Second download. + doReturn(REQUEST_ID_2) + .when(mWebContents) + .downloadImage(anyString(), anyBoolean(), anyInt(), anyBoolean(), + any(MediaImageManager.class)); + mMediaImageManager.downloadImage(mImages, mCallback); + mMediaImageManager.onFinishDownloadImage( + REQUEST_ID_2, 200, IMAGE_URL_1, mBitmaps, mOriginalImageSizes); + + verify(mWebContents, times(1)) + .downloadImage(eq(IMAGE_URL_1), eq(false), + eq(MediaImageManager.MAX_BITMAP_SIZE_FOR_DOWNLOAD), eq(false), + eq(mMediaImageManager)); + verify(mCallback, times(1)).onImageDownloaded((Bitmap) isNotNull()); + verify(mCallback, times(0)).onImageDownloaded((Bitmap) isNull()); + } + + @Test + public void testDownloadSameImageTwiceButFailed() { + // First download. + mBitmaps.clear(); + mOriginalImageSizes.clear(); + + mMediaImageManager.downloadImage(mImages, mCallback); + mMediaImageManager.onFinishDownloadImage( + REQUEST_ID_1, 404, IMAGE_URL_1, mBitmaps, mOriginalImageSizes); + + // Second download. + mMediaImageManager.downloadImage(mImages, mCallback); + // The second download request will never be initiated and the callback + // will be ignored. + mMediaImageManager.onFinishDownloadImage( + REQUEST_ID_1, 200, IMAGE_URL_1, mBitmaps, mOriginalImageSizes); + + verify(mWebContents, times(1)) + .downloadImage(eq(IMAGE_URL_1), eq(false), + eq(MediaImageManager.MAX_BITMAP_SIZE_FOR_DOWNLOAD), eq(false), + eq(mMediaImageManager)); + verify(mCallback, times(1)).onImageDownloaded((Bitmap) isNull()); + } + + @Test + public void testDownloadDifferentImagesTwice() { + // First download. + mMediaImageManager.downloadImage(mImages, mCallback); + mMediaImageManager.onFinishDownloadImage( + REQUEST_ID_1, 200, IMAGE_URL_1, mBitmaps, mOriginalImageSizes); + + // Second download. + doReturn(REQUEST_ID_2) + .when(mWebContents) + .downloadImage(anyString(), anyBoolean(), anyInt(), anyBoolean(), + any(MediaImageManager.class)); + mImages.clear(); + mImages.add(new MediaImage(IMAGE_URL_2, "", new ArrayList<Rect>())); + + mMediaImageManager.downloadImage(mImages, mCallback); + mMediaImageManager.onFinishDownloadImage( + REQUEST_ID_2, 200, IMAGE_URL_2, mBitmaps, mOriginalImageSizes); + + verify(mWebContents, times(1)) + .downloadImage(eq(IMAGE_URL_1), eq(false), + eq(MediaImageManager.MAX_BITMAP_SIZE_FOR_DOWNLOAD), eq(false), + eq(mMediaImageManager)); + verify(mWebContents, times(1)) + .downloadImage(eq(IMAGE_URL_2), eq(false), + eq(MediaImageManager.MAX_BITMAP_SIZE_FOR_DOWNLOAD), eq(false), + eq(mMediaImageManager)); + verify(mCallback, times(2)).onImageDownloaded((Bitmap) isNotNull()); + verify(mCallback, times(0)).onImageDownloaded((Bitmap) isNull()); + } + + @Test + public void testDownloadAnotherImageBeforeResponse() { + // First download. + mMediaImageManager.downloadImage(mImages, mCallback); + + // Second download. + doReturn(REQUEST_ID_2) + .when(mWebContents) + .downloadImage(anyString(), anyBoolean(), anyInt(), anyBoolean(), + any(MediaImageManager.class)); + mImages.clear(); + mImages.add(new MediaImage(IMAGE_URL_2, "", new ArrayList<Rect>())); + + mMediaImageManager.downloadImage(mImages, mCallback); + + mMediaImageManager.onFinishDownloadImage( + REQUEST_ID_2, 200, IMAGE_URL_2, mBitmaps, mOriginalImageSizes); + + // This reply should not be sent to the client. + mMediaImageManager.onFinishDownloadImage( + REQUEST_ID_1, 200, IMAGE_URL_1, mBitmaps, mOriginalImageSizes); + + verify(mWebContents, times(1)) + .downloadImage(eq(IMAGE_URL_1), eq(false), + eq(MediaImageManager.MAX_BITMAP_SIZE_FOR_DOWNLOAD), eq(false), + eq(mMediaImageManager)); + verify(mWebContents, times(1)) + .downloadImage(eq(IMAGE_URL_2), eq(false), + eq(MediaImageManager.MAX_BITMAP_SIZE_FOR_DOWNLOAD), eq(false), + eq(mMediaImageManager)); + + verify(mCallback, times(1)).onImageDownloaded((Bitmap) isNotNull()); + verify(mCallback, times(0)).onImageDownloaded((Bitmap) isNull()); + } + + @Test + public void testDuplicateResponce() { + mMediaImageManager.downloadImage(mImages, mCallback); + mMediaImageManager.onFinishDownloadImage( + REQUEST_ID_1, 200, IMAGE_URL_1, mBitmaps, mOriginalImageSizes); + mMediaImageManager.onFinishDownloadImage( + REQUEST_ID_1, 200, IMAGE_URL_1, mBitmaps, mOriginalImageSizes); + + verify(mCallback, times(1)).onImageDownloaded((Bitmap) isNotNull()); + verify(mCallback, times(0)).onImageDownloaded((Bitmap) isNull()); + } + + @Test + public void testWrongResponceId() { + mMediaImageManager.downloadImage(mImages, mCallback); + mMediaImageManager.onFinishDownloadImage( + REQUEST_ID_2, 200, IMAGE_URL_1, mBitmaps, mOriginalImageSizes); + + verify(mCallback, times(0)).onImageDownloaded((Bitmap) isNotNull()); + verify(mCallback, times(0)).onImageDownloaded((Bitmap) isNull()); + } + + @Test + public void testTinyImagesRemovedBeforeDownloading() { + mImages.clear(); + ArrayList<Rect> sizes = new ArrayList<Rect>(); + sizes.add(new Rect(0, 0, TINY_IMAGE_SIZE_PX, TINY_IMAGE_SIZE_PX)); + mImages.add(new MediaImage(IMAGE_URL_1, "", sizes)); + mMediaImageManager.downloadImage(mImages, mCallback); + + verify(mWebContents, times(0)) + .downloadImage(anyString(), anyBoolean(), anyInt(), anyBoolean(), + any(MediaImageManager.class)); + verify(mCallback).onImageDownloaded((Bitmap) isNull()); + verify(mCallback, times(0)).onImageDownloaded((Bitmap) isNotNull()); + } + + @Test + public void testTinyImagesRemovedAfterDownloading() { + mMediaImageManager.downloadImage(mImages, mCallback); + + // Reset the data for feeding. + mBitmaps.clear(); + mBitmaps.add(Bitmap.createBitmap( + TINY_IMAGE_SIZE_PX, TINY_IMAGE_SIZE_PX, Bitmap.Config.ARGB_8888)); + mOriginalImageSizes.clear(); + mOriginalImageSizes.add(new Rect(0, 0, TINY_IMAGE_SIZE_PX, TINY_IMAGE_SIZE_PX)); + + mMediaImageManager.onFinishDownloadImage( + REQUEST_ID_1, 200, IMAGE_URL_1, mBitmaps, mOriginalImageSizes); + + verify(mCallback).onImageDownloaded((Bitmap) isNull()); + verify(mCallback, times(0)).onImageDownloaded((Bitmap) isNotNull()); + } + + @Test + public void testDownloadImageFails() { + mMediaImageManager.downloadImage(mImages, mCallback); + mMediaImageManager.onFinishDownloadImage( + REQUEST_ID_1, 404, IMAGE_URL_1, new ArrayList<Bitmap>(), new ArrayList<Rect>()); + + verify(mCallback).onImageDownloaded((Bitmap) isNull()); + verify(mCallback, times(0)).onImageDownloaded((Bitmap) isNotNull()); + } + + @Test + public void testEmptyImageList() { + mImages.clear(); + mMediaImageManager.downloadImage(mImages, mCallback); + + verify(mWebContents, times(0)) + .downloadImage(anyString(), anyBoolean(), anyInt(), anyBoolean(), + any(MediaImageManager.class)); + verify(mCallback).onImageDownloaded((Bitmap) isNull()); + verify(mCallback, times(0)).onImageDownloaded((Bitmap) isNotNull()); + } + + @Test + public void testNullImageList() { + mMediaImageManager.downloadImage(null, mCallback); + + verify(mWebContents, times(0)) + .downloadImage(anyString(), anyBoolean(), anyInt(), anyBoolean(), + any(MediaImageManager.class)); + verify(mCallback).onImageDownloaded((Bitmap) isNull()); + verify(mCallback, times(0)).onImageDownloaded((Bitmap) isNotNull()); + } +} diff --git a/chromium/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaNotificationButtonComputationTest.java b/chromium/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaNotificationButtonComputationTest.java new file mode 100644 index 00000000000..94432be5b16 --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaNotificationButtonComputationTest.java @@ -0,0 +1,96 @@ +// Copyright 2016 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.components.browser_ui.media; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; + +import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.base.test.util.Feature; +import org.chromium.media_session.mojom.MediaSessionAction; + +import java.util.ArrayList; + +/** + * Robolectric tests for compact view button computation in {@link MediaNotificationController}. + */ +@RunWith(BaseRobolectricTestRunner.class) +@Config(manifest = Config.NONE) +public class MediaNotificationButtonComputationTest { + @Test + @Feature({"MediaNotification"}) + public void testLessThanThreeActionsWillBeAllShownInCompactView() { + ArrayList<Integer> actions = new ArrayList<>(); + actions.add(MediaSessionAction.NEXT_TRACK); + actions.add(MediaSessionAction.SEEK_FORWARD); + actions.add(MediaSessionAction.PLAY); + + int[] compactViewActions = + MediaNotificationController.computeCompactViewActionIndices(actions); + + assertEquals(3, compactViewActions.length); + assertEquals(0, compactViewActions[0]); + assertEquals(1, compactViewActions[1]); + assertEquals(2, compactViewActions[2]); + } + + @Test + @Feature({"MediaNotification"}) + public void testCompactViewPrefersActionPairs_SwitchTrack() { + ArrayList<Integer> actions = new ArrayList<>(); + actions.add(MediaSessionAction.PREVIOUS_TRACK); + actions.add(MediaSessionAction.NEXT_TRACK); + actions.add(MediaSessionAction.SEEK_FORWARD); + actions.add(MediaSessionAction.PLAY); + + int[] compactViewActions = + MediaNotificationController.computeCompactViewActionIndices(actions); + + assertEquals(3, compactViewActions.length); + assertEquals(0, compactViewActions[0]); + assertEquals(3, compactViewActions[1]); + assertEquals(1, compactViewActions[2]); + } + + @Test + @Feature({"MediaNotification"}) + public void testCompactViewPrefersActionPairs_Seek() { + ArrayList<Integer> actions = new ArrayList<>(); + actions.add(MediaSessionAction.NEXT_TRACK); + actions.add(MediaSessionAction.SEEK_BACKWARD); + actions.add(MediaSessionAction.SEEK_FORWARD); + actions.add(MediaSessionAction.PLAY); + + int[] compactViewActions = + MediaNotificationController.computeCompactViewActionIndices(actions); + + assertEquals(3, compactViewActions.length); + assertEquals(1, compactViewActions[0]); + assertEquals(3, compactViewActions[1]); + assertEquals(2, compactViewActions[2]); + } + + @Test + @Feature({"MediaNotification"}) + public void testCompactViewPreferSwitchTrackWhenBothPairsExist() { + ArrayList<Integer> actions = new ArrayList<>(); + actions.add(MediaSessionAction.PREVIOUS_TRACK); + actions.add(MediaSessionAction.NEXT_TRACK); + actions.add(MediaSessionAction.SEEK_BACKWARD); + actions.add(MediaSessionAction.SEEK_FORWARD); + actions.add(MediaSessionAction.PLAY); + + int[] compactViewActions = + MediaNotificationController.computeCompactViewActionIndices(actions); + + assertEquals(3, compactViewActions.length); + assertEquals(0, compactViewActions[0]); + assertEquals(4, compactViewActions[1]); + assertEquals(1, compactViewActions[2]); + } +} diff --git a/chromium/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaNotificationController.java b/chromium/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaNotificationController.java new file mode 100644 index 00000000000..819ddde1e61 --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaNotificationController.java @@ -0,0 +1,905 @@ +// Copyright 2020 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.components.browser_ui.media; + +import android.app.PendingIntent; +import android.app.Service; +import android.content.Context; +import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.media.AudioManager; +import android.os.Build; +import android.os.Handler; +import android.support.v4.media.MediaMetadataCompat; +import android.support.v4.media.session.MediaSessionCompat; +import android.support.v4.media.session.PlaybackStateCompat; +import android.text.TextUtils; +import android.util.SparseArray; + +import androidx.annotation.NonNull; +import androidx.annotation.VisibleForTesting; +import androidx.core.app.NotificationCompat; +import androidx.core.app.NotificationManagerCompat; + +import org.chromium.base.CollectionUtil; +import org.chromium.base.ContextUtils; +import org.chromium.base.Log; +import org.chromium.components.browser_ui.notifications.ChromeNotification; +import org.chromium.components.browser_ui.notifications.ChromeNotificationBuilder; +import org.chromium.components.browser_ui.notifications.ForegroundServiceUtils; +import org.chromium.components.browser_ui.notifications.NotificationManagerProxy; +import org.chromium.components.browser_ui.notifications.NotificationManagerProxyImpl; +import org.chromium.media_session.mojom.MediaSessionAction; +import org.chromium.services.media_session.MediaMetadata; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * A class that manages the notification, foreground service, and {@link MediaSessionCompat} for a + * specific type of media. + */ +public class MediaNotificationController { + private static final String TAG = "MediaNotification"; + + // The maximum number of actions in CompactView media notification. + private static final int COMPACT_VIEW_ACTIONS_COUNT = 3; + + // The maximum number of actions in BigView media notification. + private static final int BIG_VIEW_ACTIONS_COUNT = 5; + + // These string values reflect legacy class hierarchy. + public static final String ACTION_PLAY = "MediaNotificationManager.ListenerService.PLAY"; + public static final String ACTION_PAUSE = "MediaNotificationManager.ListenerService.PAUSE"; + public static final String ACTION_STOP = "MediaNotificationManager.ListenerService.STOP"; + public static final String ACTION_SWIPE = "MediaNotificationManager.ListenerService.SWIPE"; + public static final String ACTION_CANCEL = "MediaNotificationManager.ListenerService.CANCEL"; + public static final String ACTION_PREVIOUS_TRACK = + "MediaNotificationManager.ListenerService.PREVIOUS_TRACK"; + public static final String ACTION_NEXT_TRACK = + "MediaNotificationManager.ListenerService.NEXT_TRACK"; + public static final String ACTION_SEEK_FORWARD = + "MediaNotificationManager.ListenerService.SEEK_FORWARD"; + public static final String ACTION_SEEK_BACKWARD = + "MediaNotificationmanager.ListenerService.SEEK_BACKWARD"; + + // Overrides N detection. The production code will use |null|, which uses the Android version + // code. Otherwise, |isRunningAtLeastN()| will return whatever value is set. + @VisibleForTesting + public static Boolean sOverrideIsRunningNForTesting; + + // ListenerService running for the notification. Only non-null when showing. + @VisibleForTesting + public Service mService; + + @VisibleForTesting + public Delegate mDelegate; + + private SparseArray<MediaButtonInfo> mActionToButtonInfo; + + @VisibleForTesting + public ChromeNotificationBuilder mNotificationBuilder; + + @VisibleForTesting + public Bitmap mDefaultNotificationLargeIcon; + + // |mMediaNotificationInfo| should be not null if and only if the notification is showing. + @VisibleForTesting + public MediaNotificationInfo mMediaNotificationInfo; + + @VisibleForTesting + public MediaSessionCompat mMediaSession; + + @VisibleForTesting + public Throttler mThrottler; + + @VisibleForTesting + public static class Throttler { + @VisibleForTesting + public static final int THROTTLE_MILLIS = 500; + + @VisibleForTesting + public MediaNotificationController mController; + + private final Handler mHandler; + + @VisibleForTesting + public Throttler(@NonNull MediaNotificationController manager) { + mController = manager; + mHandler = new Handler(); + } + + // When |mTask| is non-null, it will always be queued in mHandler. When |mTask| is non-null, + // all notification updates will be throttled and their info will be stored as + // mLastPendingInfo. When |mTask| fires, it will call {@link showNotification()} with + // the latest queued notification info. + @VisibleForTesting + public Runnable mTask; + + // The last pending info. If non-null, it will be the latest notification info. + // Otherwise, the latest notification info will be |mController.mMediaNotificationInfo|. + @VisibleForTesting + public MediaNotificationInfo mLastPendingInfo; + + /** + * Queue |mediaNotificationInfo| for update. In unthrottled state (i.e. |mTask| != null), + * the notification will be updated immediately and enter the throttled state. In + * unthrottled state, the method will only update the pending notification info, which will + * be used for updating the notification when |mTask| is fired. + * + * @param mediaNotificationInfo The notification info to be queued. + */ + public void queueNotification(MediaNotificationInfo mediaNotificationInfo) { + assert mediaNotificationInfo != null; + + MediaNotificationInfo latestMediaNotificationInfo = mLastPendingInfo != null + ? mLastPendingInfo + : mController.mMediaNotificationInfo; + + if (shouldIgnoreMediaNotificationInfo( + latestMediaNotificationInfo, mediaNotificationInfo)) { + return; + } + + if (mTask == null) { + showNotificationImmediately(mediaNotificationInfo); + } else { + mLastPendingInfo = mediaNotificationInfo; + } + } + + /** + * Clears the pending notification and enter unthrottled state. + */ + public void clearPendingNotifications() { + mHandler.removeCallbacks(mTask); + mLastPendingInfo = null; + mTask = null; + } + + @VisibleForTesting + public void showNotificationImmediately(MediaNotificationInfo mediaNotificationInfo) { + // If no notification hasn't been updated in the last THROTTLE_MILLIS, update + // immediately and queue a task for blocking further updates. + mController.showNotification(mediaNotificationInfo); + mTask = new Runnable() { + @Override + public void run() { + if (mLastPendingInfo != null) { + // If any notification info is pended during the throttling time window, + // update the notification. + showNotificationImmediately(mLastPendingInfo); + mLastPendingInfo = null; + } else { + // Otherwise, clear the task so further update is unthrottled. + mTask = null; + } + } + }; + if (!mHandler.postDelayed(mTask, THROTTLE_MILLIS)) { + Log.w(TAG, "Failed to post the throttler task."); + mTask = null; + } + } + } + + private final MediaSessionCompat + .Callback mMediaSessionCallback = new MediaSessionCompat.Callback() { + @Override + public void onPlay() { + MediaNotificationController.this.onPlay( + MediaNotificationListener.ACTION_SOURCE_MEDIA_SESSION); + } + + @Override + public void onPause() { + MediaNotificationController.this.onPause( + MediaNotificationListener.ACTION_SOURCE_MEDIA_SESSION); + } + + @Override + public void onSkipToPrevious() { + MediaNotificationController.this.onMediaSessionAction( + MediaSessionAction.PREVIOUS_TRACK); + } + + @Override + public void onSkipToNext() { + MediaNotificationController.this.onMediaSessionAction(MediaSessionAction.NEXT_TRACK); + } + + @Override + public void onFastForward() { + MediaNotificationController.this.onMediaSessionAction(MediaSessionAction.SEEK_FORWARD); + } + + @Override + public void onRewind() { + MediaNotificationController.this.onMediaSessionAction(MediaSessionAction.SEEK_BACKWARD); + } + + @Override + public void onSeekTo(long pos) { + MediaNotificationController.this.onMediaSessionSeekTo(pos); + } + }; + + /** + * Finishes starting the service on O+. + * + * If startForegroundService() was called, the app MUST call startForeground on the created + * service no matter what or it will crash. + * + * @param service the {@link Service} on which {@link Context#startForegroundService()} has been + * called. + * @param notification a minimal version of the notification associated with the service. + * @return true if {@link Service#startForeground()} was called. + */ + public static boolean finishStartingForegroundServiceOnO( + Service service, ChromeNotification notification) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return false; + ForegroundServiceUtils.getInstance().startForeground(service, notification.getMetadata().id, + notification.getNotification(), 0 /* foregroundServiceType */); + return true; + } + + private PendingIntent createPendingIntent(String action) { + Intent intent = mDelegate.createServiceIntent().setAction(action); + return PendingIntent.getService(getContext(), 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); + } + + private static boolean isRunningAtLeastN() { + return (sOverrideIsRunningNForTesting != null) + ? sOverrideIsRunningNForTesting + : Build.VERSION.SDK_INT >= Build.VERSION_CODES.N; + } + + /** + * The class containing all the information for adding a button in the notification for an + * action. + */ + private static final class MediaButtonInfo { + /** The resource ID of this media button icon. */ + public int iconResId; + + /** The resource ID of this media button description. */ + public int descriptionResId; + + /** The intent string to be fired when this media button is clicked. */ + public String intentString; + + public MediaButtonInfo(int buttonResId, int descriptionResId, String intentString) { + this.iconResId = buttonResId; + this.descriptionResId = descriptionResId; + this.intentString = intentString; + } + } + + /** An interface for separating embedder-specific logic. */ + public interface Delegate { + /** Returns an intent that will start a Service which listens to notification actions. */ + Intent createServiceIntent(); + + /** Returns the name of the embedding app. */ + String getAppName(); + + /** Returns the notification group name used to prevent automatic grouping. */ + String getNotificationGroupName(); + + /** Returns a builder suitable as a starting point for creating the notification. */ + ChromeNotificationBuilder createChromeNotificationBuilder(); + + /** Called when the Android MediaSession has been updated. */ + void onMediaSessionUpdated(MediaSessionCompat session); + + /** Called when a notification has been shown and should be logged in UMA. */ + void logNotificationShown(ChromeNotification notification); + } + + public MediaNotificationController(Delegate delegate) { + mDelegate = delegate; + + mActionToButtonInfo = new SparseArray<>(); + + mActionToButtonInfo.put(MediaSessionAction.PLAY, + new MediaButtonInfo(R.drawable.ic_play_arrow_white_36dp, + R.string.accessibility_play, ACTION_PLAY)); + mActionToButtonInfo.put(MediaSessionAction.PAUSE, + new MediaButtonInfo(R.drawable.ic_pause_white_36dp, R.string.accessibility_pause, + ACTION_PAUSE)); + mActionToButtonInfo.put(MediaSessionAction.STOP, + new MediaButtonInfo( + R.drawable.ic_stop_white_36dp, R.string.accessibility_stop, ACTION_STOP)); + mActionToButtonInfo.put(MediaSessionAction.PREVIOUS_TRACK, + new MediaButtonInfo(R.drawable.ic_skip_previous_white_36dp, + R.string.accessibility_previous_track, ACTION_PREVIOUS_TRACK)); + mActionToButtonInfo.put(MediaSessionAction.NEXT_TRACK, + new MediaButtonInfo(R.drawable.ic_skip_next_white_36dp, + R.string.accessibility_next_track, ACTION_NEXT_TRACK)); + mActionToButtonInfo.put(MediaSessionAction.SEEK_FORWARD, + new MediaButtonInfo(R.drawable.ic_fast_forward_white_36dp, + R.string.accessibility_seek_forward, ACTION_SEEK_FORWARD)); + mActionToButtonInfo.put(MediaSessionAction.SEEK_BACKWARD, + new MediaButtonInfo(R.drawable.ic_fast_rewind_white_36dp, + R.string.accessibility_seek_backward, ACTION_SEEK_BACKWARD)); + + mThrottler = new Throttler(this); + } + + /** + * Registers the started {@link Service} with the manager and creates the notification. + * + * @param service the service that was started + */ + public void onServiceStarted(Service service) { + if (mService == service) return; + + mService = service; + updateNotification(true /*serviceStarting*/, true /*shouldLogNotification*/); + } + + /** Handles the service destruction. */ + public void onServiceDestroyed() { + mService = null; + } + + public boolean processIntent(Service service, Intent intent) { + if (intent == null || mMediaNotificationInfo == null) return false; + + if (intent.getAction() == null) { + // The intent comes from {@link AppHooks#startForegroundService}. + onServiceStarted(service); + } else { + // The intent comes from the notification. In this case, {@link onServiceStarted()} + // does need to be called. + processAction(intent.getAction()); + } + return true; + } + + public void processAction(String action) { + if (ACTION_STOP.equals(action) || ACTION_SWIPE.equals(action) + || ACTION_CANCEL.equals(action)) { + onStop(MediaNotificationListener.ACTION_SOURCE_MEDIA_NOTIFICATION); + stopListenerService(); + } else if (ACTION_PLAY.equals(action)) { + onPlay(MediaNotificationListener.ACTION_SOURCE_MEDIA_NOTIFICATION); + } else if (ACTION_PAUSE.equals(action)) { + onPause(MediaNotificationListener.ACTION_SOURCE_MEDIA_NOTIFICATION); + } else if (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(action)) { + onPause(MediaNotificationListener.ACTION_SOURCE_HEADSET_UNPLUG); + } else if (ACTION_PREVIOUS_TRACK.equals(action)) { + onMediaSessionAction(MediaSessionAction.PREVIOUS_TRACK); + } else if (ACTION_NEXT_TRACK.equals(action)) { + onMediaSessionAction(MediaSessionAction.NEXT_TRACK); + } else if (ACTION_SEEK_FORWARD.equals(action)) { + onMediaSessionAction(MediaSessionAction.SEEK_FORWARD); + } else if (ACTION_SEEK_BACKWARD.equals(action)) { + onMediaSessionAction(MediaSessionAction.SEEK_BACKWARD); + } + } + + @VisibleForTesting + public void onPlay(int actionSource) { + // MediaSessionCompat calls this sometimes when `mMediaNotificationInfo` + // is no longer available. It's unclear if it is a Support Library issue + // or something that isn't properly cleaned up but given that the + // crashes are rare and the fix is simple, null check was enough. + if (mMediaNotificationInfo == null || !mMediaNotificationInfo.isPaused) return; + mMediaNotificationInfo.listener.onPlay(actionSource); + } + + @VisibleForTesting + public void onPause(int actionSource) { + // MediaSessionCompat calls this sometimes when `mMediaNotificationInfo` + // is no longer available. It's unclear if it is a Support Library issue + // or something that isn't properly cleaned up but given that the + // crashes are rare and the fix is simple, null check was enough. + if (mMediaNotificationInfo == null || mMediaNotificationInfo.isPaused) return; + mMediaNotificationInfo.listener.onPause(actionSource); + } + + @VisibleForTesting + public void onStop(int actionSource) { + // MediaSessionCompat calls this sometimes when `mMediaNotificationInfo` + // is no longer available. It's unclear if it is a Support Library issue + // or something that isn't properly cleaned up but given that the + // crashes are rare and the fix is simple, null check was enough. + if (mMediaNotificationInfo == null) return; + mMediaNotificationInfo.listener.onStop(actionSource); + } + + @VisibleForTesting + public void onMediaSessionAction(int action) { + // MediaSessionCompat calls this sometimes when `mMediaNotificationInfo` + // is no longer available. It's unclear if it is a Support Library issue + // or something that isn't properly cleaned up but given that the + // crashes are rare and the fix is simple, null check was enough. + if (mMediaNotificationInfo == null) return; + mMediaNotificationInfo.listener.onMediaSessionAction(action); + } + + @VisibleForTesting + void onMediaSessionSeekTo(long pos) { + // MediaSessionCompat calls this sometimes when `mMediaNotificationInfo` + // is no longer available. It's unclear if it is a Support Library issue + // or something that isn't properly cleaned up but given that the + // crashes are rare and the fix is simple, null check was enough. + if (mMediaNotificationInfo == null) return; + mMediaNotificationInfo.listener.onMediaSessionSeekTo(pos); + } + + @VisibleForTesting + public void showNotification(MediaNotificationInfo mediaNotificationInfo) { + if (shouldIgnoreMediaNotificationInfo(mMediaNotificationInfo, mediaNotificationInfo)) { + return; + } + + mMediaNotificationInfo = mediaNotificationInfo; + + // If there's no pending service start request, don't try to start service. If there is a + // pending service start request but the service haven't started yet, only update the + // |mMediaNotificationInfo|. The service will update the notification later once it's + // started. + if (mService == null && mediaNotificationInfo.isPaused) return; + + if (mService == null) { + updateMediaSession(); + updateNotificationBuilder(); + ForegroundServiceUtils.getInstance().startForegroundService( + mDelegate.createServiceIntent()); + } else { + updateNotification(false, false); + } + } + + private static boolean shouldIgnoreMediaNotificationInfo( + MediaNotificationInfo oldInfo, MediaNotificationInfo newInfo) { + // If we don't have actions then we shouldn't display the notification. + if (newInfo.mediaSessionActions.isEmpty()) return true; + + return newInfo.equals(oldInfo) + || ((newInfo.isPaused && oldInfo != null + && newInfo.instanceId != oldInfo.instanceId)); + } + + public void clearNotification() { + mThrottler.clearPendingNotifications(); + if (mMediaNotificationInfo == null) return; + + NotificationManagerCompat.from(getContext()).cancel(mMediaNotificationInfo.id); + + if (mMediaSession != null) { + mMediaSession.setCallback(null); + mMediaSession.setActive(false); + mMediaSession.release(); + mMediaSession = null; + } + stopListenerService(); + mMediaNotificationInfo = null; + mNotificationBuilder = null; + } + + public void queueNotification(MediaNotificationInfo mediaNotificationInfo) { + mThrottler.queueNotification(mediaNotificationInfo); + } + + public void hideNotification(int instanceId) { + if (mMediaNotificationInfo == null || instanceId != mMediaNotificationInfo.instanceId) { + return; + } + clearNotification(); + } + + @VisibleForTesting + public void stopListenerService() { + if (mService == null) return; + + ForegroundServiceUtils.getInstance().stopForeground( + mService, Service.STOP_FOREGROUND_REMOVE); + mService.stopSelf(); + } + + @NonNull + @VisibleForTesting + public MediaMetadataCompat createMetadata() { + // Can't return null as {@link MediaSessionCompat#setMetadata()} will crash in some versions + // of the Android compat library. + MediaMetadataCompat.Builder metadataBuilder = new MediaMetadataCompat.Builder(); + if (mMediaNotificationInfo.isPrivate) return metadataBuilder.build(); + + metadataBuilder.putString( + MediaMetadataCompat.METADATA_KEY_TITLE, mMediaNotificationInfo.metadata.getTitle()); + metadataBuilder.putString( + MediaMetadataCompat.METADATA_KEY_ARTIST, mMediaNotificationInfo.origin); + + if (!TextUtils.isEmpty(mMediaNotificationInfo.metadata.getArtist())) { + metadataBuilder.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, + mMediaNotificationInfo.metadata.getArtist()); + } + if (!TextUtils.isEmpty(mMediaNotificationInfo.metadata.getAlbum())) { + metadataBuilder.putString(MediaMetadataCompat.METADATA_KEY_ALBUM, + mMediaNotificationInfo.metadata.getAlbum()); + } + if (mMediaNotificationInfo.mediaSessionImage != null) { + metadataBuilder.putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, + mMediaNotificationInfo.mediaSessionImage); + } + if (mMediaNotificationInfo.mediaPosition != null) { + metadataBuilder.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, + mMediaNotificationInfo.mediaPosition.getDuration()); + } + + return metadataBuilder.build(); + } + + @VisibleForTesting + public void updateNotification(boolean serviceStarting, boolean shouldLogNotification) { + if (mService == null) return; + + if (mMediaNotificationInfo == null) { + if (serviceStarting) { + finishStartingForegroundServiceOnO(mService, + mDelegate.createChromeNotificationBuilder().buildChromeNotification()); + ForegroundServiceUtils.getInstance().stopForeground( + mService, Service.STOP_FOREGROUND_REMOVE); + } + return; + } + updateMediaSession(); + updateNotificationBuilder(); + + ChromeNotification notification = mNotificationBuilder.buildChromeNotification(); + + // On O, finish starting the foreground service nevertheless, or Android will + // crash Chrome. + boolean finishedForegroundingService = + serviceStarting && finishStartingForegroundServiceOnO(mService, notification); + + // We keep the service as a foreground service while the media is playing. When it is not, + // the service isn't stopped but is no longer in foreground, thus at a lower priority. + // While the service is in foreground, the associated notification can't be swipped away. + // Moving it back to background allows the user to remove the notification. + if (mMediaNotificationInfo.supportsSwipeAway() && mMediaNotificationInfo.isPaused) { + ForegroundServiceUtils.getInstance().stopForeground( + mService, Service.STOP_FOREGROUND_DETACH); + NotificationManagerProxy manager = new NotificationManagerProxyImpl(getContext()); + manager.notify(notification); + } else if (!finishedForegroundingService) { + ForegroundServiceUtils.getInstance().startForeground(mService, + mMediaNotificationInfo.id, notification.getNotification(), + 0 /*foregroundServiceType*/); + } + if (shouldLogNotification) { + mDelegate.logNotificationShown(notification); + } + } + + @VisibleForTesting + public void updateNotificationBuilder() { + assert (mMediaNotificationInfo != null); + + mNotificationBuilder = mDelegate.createChromeNotificationBuilder(); + setMediaStyleLayoutForNotificationBuilder(mNotificationBuilder); + + // TODO(zqzhang): It's weird that setShowWhen() doesn't work on K. Calling setWhen() to + // force removing the time. + mNotificationBuilder.setShowWhen(false).setWhen(0); + mNotificationBuilder.setSmallIcon(mMediaNotificationInfo.notificationSmallIcon); + mNotificationBuilder.setAutoCancel(false); + mNotificationBuilder.setLocalOnly(true); + mNotificationBuilder.setGroup(mDelegate.getNotificationGroupName()); + mNotificationBuilder.setGroupSummary(true); + + if (mMediaNotificationInfo.supportsSwipeAway()) { + mNotificationBuilder.setOngoing(!mMediaNotificationInfo.isPaused); + mNotificationBuilder.setDeleteIntent(createPendingIntent(ACTION_SWIPE)); + } + + // The intent will currently only be null when using a custom tab. + // TODO(avayvod) work out what we should do in this case. See https://crbug.com/585395. + if (mMediaNotificationInfo.contentIntent != null) { + mNotificationBuilder.setContentIntent(PendingIntent.getActivity(getContext(), + mMediaNotificationInfo.instanceId, mMediaNotificationInfo.contentIntent, + PendingIntent.FLAG_UPDATE_CURRENT)); + // Set FLAG_UPDATE_CURRENT so that the intent extras is updated, otherwise the + // intent extras will stay the same for the same tab. + } + + mNotificationBuilder.setVisibility(mMediaNotificationInfo.isPrivate + ? NotificationCompat.VISIBILITY_PRIVATE + : NotificationCompat.VISIBILITY_PUBLIC); + } + + @VisibleForTesting + public void updateMediaSession() { + if (!mMediaNotificationInfo.supportsPlayPause()) return; + + if (mMediaSession == null) mMediaSession = createMediaSession(); + + activateAndroidMediaSession(mMediaNotificationInfo.instanceId); + + mDelegate.onMediaSessionUpdated(mMediaSession); + + mMediaSession.setMetadata(createMetadata()); + + mMediaSession.setPlaybackState(createPlaybackState()); + } + + @VisibleForTesting + public PlaybackStateCompat createPlaybackState() { + PlaybackStateCompat.Builder playbackStateBuilder = + new PlaybackStateCompat.Builder().setActions(computeMediaSessionActions()); + + int state = mMediaNotificationInfo.isPaused ? PlaybackStateCompat.STATE_PAUSED + : PlaybackStateCompat.STATE_PLAYING; + + if (mMediaNotificationInfo.mediaPosition != null) { + playbackStateBuilder.setState(state, mMediaNotificationInfo.mediaPosition.getPosition(), + mMediaNotificationInfo.mediaPosition.getPlaybackRate(), + mMediaNotificationInfo.mediaPosition.getLastUpdatedTime()); + } else { + playbackStateBuilder.setState( + state, PlaybackStateCompat.PLAYBACK_POSITION_UNKNOWN, 1.0f); + } + + return playbackStateBuilder.build(); + } + + private long computeMediaSessionActions() { + assert mMediaNotificationInfo != null; + + long actions = PlaybackStateCompat.ACTION_PLAY | PlaybackStateCompat.ACTION_PAUSE; + if (mMediaNotificationInfo.mediaSessionActions.contains( + MediaSessionAction.PREVIOUS_TRACK)) { + actions |= PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS; + } + if (mMediaNotificationInfo.mediaSessionActions.contains(MediaSessionAction.NEXT_TRACK)) { + actions |= PlaybackStateCompat.ACTION_SKIP_TO_NEXT; + } + if (mMediaNotificationInfo.mediaSessionActions.contains(MediaSessionAction.SEEK_FORWARD)) { + actions |= PlaybackStateCompat.ACTION_FAST_FORWARD; + } + if (mMediaNotificationInfo.mediaSessionActions.contains(MediaSessionAction.SEEK_BACKWARD)) { + actions |= PlaybackStateCompat.ACTION_REWIND; + } + if (mMediaNotificationInfo.mediaSessionActions.contains(MediaSessionAction.SEEK_TO)) { + actions |= PlaybackStateCompat.ACTION_SEEK_TO; + } + return actions; + } + + private MediaSessionCompat createMediaSession() { + MediaSessionCompat mediaSession = + new MediaSessionCompat(getContext(), mDelegate.getAppName()); + mediaSession.setCallback(mMediaSessionCallback); + mediaSession.setActive(true); + return mediaSession; + } + + /** + * Activates the media session. + * @param instanceId the instance of the notification to activate. If it doesn't match the + * active notification, this method will no-op. + */ + public void activateAndroidMediaSession(int instanceId) { + if (mMediaNotificationInfo == null) return; + if (mMediaNotificationInfo.instanceId != instanceId) return; + if (!mMediaNotificationInfo.supportsPlayPause() || mMediaNotificationInfo.isPaused) return; + if (mMediaSession == null) return; + mMediaSession.setActive(true); + } + + private void setMediaStyleLayoutForNotificationBuilder(ChromeNotificationBuilder builder) { + setMediaStyleNotificationText(builder); + if (!mMediaNotificationInfo.supportsPlayPause()) { + // Non-playback (Cast) notification will not use MediaStyle, so not + // setting the large icon is fine. + builder.setLargeIcon(null); + // Notifications in incognito shouldn't show an icon to avoid leaking information. + } else if (mMediaNotificationInfo.notificationLargeIcon != null + && !mMediaNotificationInfo.isPrivate) { + builder.setLargeIcon(mMediaNotificationInfo.notificationLargeIcon); + } else if (!isRunningAtLeastN()) { + if (mDefaultNotificationLargeIcon == null + && mMediaNotificationInfo.defaultNotificationLargeIcon != 0) { + mDefaultNotificationLargeIcon = + MediaNotificationImageUtils.downscaleIconToIdealSize( + BitmapFactory.decodeResource(getContext().getResources(), + mMediaNotificationInfo.defaultNotificationLargeIcon)); + } + builder.setLargeIcon(mDefaultNotificationLargeIcon); + } + + addNotificationButtons(builder); + } + + private void addNotificationButtons(ChromeNotificationBuilder builder) { + Set<Integer> actions = new HashSet<>(); + + // TODO(zqzhang): handle other actions when play/pause is not supported? See + // https://crbug.com/667500 + if (mMediaNotificationInfo.supportsPlayPause()) { + actions.addAll(mMediaNotificationInfo.mediaSessionActions); + if (mMediaNotificationInfo.isPaused) { + actions.remove(MediaSessionAction.PAUSE); + actions.add(MediaSessionAction.PLAY); + } else { + actions.remove(MediaSessionAction.PLAY); + actions.add(MediaSessionAction.PAUSE); + } + } + + if (mMediaNotificationInfo.supportsStop()) { + actions.add(MediaSessionAction.STOP); + } else { + actions.remove(MediaSessionAction.STOP); + } + + List<Integer> bigViewActions = computeBigViewActions(actions); + + for (int action : bigViewActions) { + MediaButtonInfo buttonInfo = mActionToButtonInfo.get(action); + builder.addAction(buttonInfo.iconResId, + getContext().getResources().getString(buttonInfo.descriptionResId), + createPendingIntent(buttonInfo.intentString)); + } + + // Only apply MediaStyle when NotificationInfo supports play/pause. + if (mMediaNotificationInfo.supportsPlayPause()) { + builder.setMediaStyle(mMediaSession, computeCompactViewActionIndices(bigViewActions), + createPendingIntent(ACTION_CANCEL), true); + } + } + + private void setMediaStyleNotificationText(ChromeNotificationBuilder builder) { + if (mMediaNotificationInfo.isPrivate) { + // Notifications in incognito shouldn't show what is playing to avoid leaking + // information. + if (isRunningAtLeastN()) { + builder.setContentTitle(getContext().getResources().getString( + R.string.media_notification_incognito)); + builder.setSubText( + getContext().getResources().getString(R.string.notification_incognito_tab)); + } else { + // App name is automatically added to the title from Android N, + // but needs to be added explicitly for prior versions. + builder.setContentTitle(mDelegate.getAppName()) + .setContentText(getContext().getResources().getString( + R.string.media_notification_incognito)); + } + return; + } + + builder.setContentTitle(mMediaNotificationInfo.metadata.getTitle()); + String artistAndAlbumText = getArtistAndAlbumText(mMediaNotificationInfo.metadata); + if (isRunningAtLeastN() || !artistAndAlbumText.isEmpty()) { + builder.setContentText(artistAndAlbumText); + builder.setSubText(mMediaNotificationInfo.origin); + } else { + // Leaving ContentText empty looks bad, so move origin up to the ContentText. + builder.setContentText(mMediaNotificationInfo.origin); + } + } + + private static String getArtistAndAlbumText(MediaMetadata metadata) { + String artist = (metadata.getArtist() == null) ? "" : metadata.getArtist(); + String album = (metadata.getAlbum() == null) ? "" : metadata.getAlbum(); + if (artist.isEmpty() || album.isEmpty()) { + return artist + album; + } + return artist + " - " + album; + } + + /** + * Compute the actions to be shown in BigView media notification. + * + * The method assumes STOP cannot coexist with switch track actions and seeking actions. It also + * assumes PLAY and PAUSE cannot coexist. + */ + private static List<Integer> computeBigViewActions(Set<Integer> actions) { + // STOP cannot coexist with switch track actions and seeking actions. + assert !actions.contains(MediaSessionAction.STOP) + || !(actions.contains(MediaSessionAction.PREVIOUS_TRACK) + && actions.contains(MediaSessionAction.NEXT_TRACK) + && actions.contains(MediaSessionAction.SEEK_BACKWARD) + && actions.contains(MediaSessionAction.SEEK_FORWARD)); + // PLAY and PAUSE cannot coexist. + assert !actions.contains(MediaSessionAction.PLAY) + || !actions.contains(MediaSessionAction.PAUSE); + + int[] actionByOrder = { + MediaSessionAction.PREVIOUS_TRACK, + MediaSessionAction.SEEK_BACKWARD, + MediaSessionAction.PLAY, + MediaSessionAction.PAUSE, + MediaSessionAction.SEEK_FORWARD, + MediaSessionAction.NEXT_TRACK, + MediaSessionAction.STOP, + }; + + // Sort the actions based on the expected ordering in the UI. + List<Integer> sortedActions = new ArrayList<>(); + for (int action : actionByOrder) { + if (actions.contains(action)) sortedActions.add(action); + } + + // There can't be move actions than BIG_VIEW_ACTIONS_COUNT. We do this check after we have + // sorted the actions since there may be more actions that we do not support. + assert sortedActions.size() <= BIG_VIEW_ACTIONS_COUNT; + + return sortedActions; + } + + /** + * Compute the actions to be shown in CompactView media notification. + * + * The method assumes STOP cannot coexist with switch track actions and seeking actions. It also + * assumes PLAY and PAUSE cannot coexist. + * + * Actions in pairs are preferred if there are more actions than |COMPACT_VIEW_ACTIONS_COUNT|. + */ + @VisibleForTesting + static int[] computeCompactViewActionIndices(List<Integer> actions) { + // STOP cannot coexist with switch track actions and seeking actions. + assert !actions.contains(MediaSessionAction.STOP) + || !(actions.contains(MediaSessionAction.PREVIOUS_TRACK) + && actions.contains(MediaSessionAction.NEXT_TRACK) + && actions.contains(MediaSessionAction.SEEK_BACKWARD) + && actions.contains(MediaSessionAction.SEEK_FORWARD)); + // PLAY and PAUSE cannot coexist. + assert !actions.contains(MediaSessionAction.PLAY) + || !actions.contains(MediaSessionAction.PAUSE); + + if (actions.size() <= COMPACT_VIEW_ACTIONS_COUNT) { + // If the number of actions is less than |COMPACT_VIEW_ACTIONS_COUNT|, just return an + // array of 0, 1, ..., |actions.size()|-1. + int[] actionsArray = new int[actions.size()]; + for (int i = 0; i < actions.size(); ++i) actionsArray[i] = i; + return actionsArray; + } + + if (actions.contains(MediaSessionAction.STOP)) { + List<Integer> compactActions = new ArrayList<>(); + if (actions.contains(MediaSessionAction.PLAY)) { + compactActions.add(actions.indexOf(MediaSessionAction.PLAY)); + } + compactActions.add(actions.indexOf(MediaSessionAction.STOP)); + return CollectionUtil.integerListToIntArray(compactActions); + } + + int[] actionsArray = new int[COMPACT_VIEW_ACTIONS_COUNT]; + if (actions.contains(MediaSessionAction.PREVIOUS_TRACK) + && actions.contains(MediaSessionAction.NEXT_TRACK)) { + actionsArray[0] = actions.indexOf(MediaSessionAction.PREVIOUS_TRACK); + if (actions.contains(MediaSessionAction.PLAY)) { + actionsArray[1] = actions.indexOf(MediaSessionAction.PLAY); + } else { + actionsArray[1] = actions.indexOf(MediaSessionAction.PAUSE); + } + actionsArray[2] = actions.indexOf(MediaSessionAction.NEXT_TRACK); + return actionsArray; + } + + assert actions.contains(MediaSessionAction.SEEK_BACKWARD) + && actions.contains(MediaSessionAction.SEEK_FORWARD); + actionsArray[0] = actions.indexOf(MediaSessionAction.SEEK_BACKWARD); + if (actions.contains(MediaSessionAction.PLAY)) { + actionsArray[1] = actions.indexOf(MediaSessionAction.PLAY); + } else { + actionsArray[1] = actions.indexOf(MediaSessionAction.PAUSE); + } + actionsArray[2] = actions.indexOf(MediaSessionAction.SEEK_FORWARD); + + return actionsArray; + } + + private static Context getContext() { + return ContextUtils.getApplicationContext(); + } +} diff --git a/chromium/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaNotificationImageUtils.java b/chromium/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaNotificationImageUtils.java new file mode 100644 index 00000000000..d5ce90feedb --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaNotificationImageUtils.java @@ -0,0 +1,74 @@ +// Copyright 2020 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.components.browser_ui.media; + +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Matrix; +import android.graphics.Paint; + +import androidx.annotation.Nullable; + +import org.chromium.base.SysUtils; + +/** A collection of utilities and constants for the images used in MediaSession notifications. */ +public class MediaNotificationImageUtils { + public static final int MINIMAL_MEDIA_IMAGE_SIZE_PX = 114; + + // The media artwork image resolution on high-end devices. + private static final int HIGH_IMAGE_SIZE_PX = 512; + + // The media artwork image resolution on high-end devices. + private static final int LOW_IMAGE_SIZE_PX = 256; + + /** + * Downscale |icon| for display in the notification if needed. Returns null if |icon| is null. + * If |icon| is larger than {@link getIdealMediaImageSize()}, scale it down to + * {@link getIdealMediaImageSize()} and return. Otherwise return the original |icon|. + * @param icon The icon to be scaled. + */ + @Nullable + public static Bitmap downscaleIconToIdealSize(@Nullable Bitmap icon) { + if (icon == null) return null; + + int targetSize = getIdealMediaImageSize(); + + Matrix m = new Matrix(); + int dominantLength = Math.max(icon.getWidth(), icon.getHeight()); + + if (dominantLength < getIdealMediaImageSize()) return icon; + + // Move the center to (0,0). + m.postTranslate(icon.getWidth() / -2.0f, icon.getHeight() / -2.0f); + // Scale to desired size. + float scale = 1.0f * targetSize / dominantLength; + m.postScale(scale, scale); + // Move to the desired place. + m.postTranslate(targetSize / 2.0f, targetSize / 2.0f); + + // Draw the image. + Bitmap paddedBitmap = Bitmap.createBitmap(targetSize, targetSize, Bitmap.Config.ARGB_8888); + Canvas canvas = new Canvas(paddedBitmap); + Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG); + canvas.drawBitmap(icon, m, paint); + return paddedBitmap; + } + + /** + * @return The ideal size of the media image. + */ + public static int getIdealMediaImageSize() { + return SysUtils.isLowEndDevice() ? LOW_IMAGE_SIZE_PX : HIGH_IMAGE_SIZE_PX; + } + + /** + * @param icon The icon to be checked. + * @return Whether |icon| is suitable as the media image, i.e. bigger than the minimal size. + */ + public static boolean isBitmapSuitableAsMediaImage(Bitmap icon) { + return icon != null && icon.getWidth() >= MINIMAL_MEDIA_IMAGE_SIZE_PX + && icon.getHeight() >= MINIMAL_MEDIA_IMAGE_SIZE_PX; + } +} diff --git a/chromium/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaNotificationInfo.java b/chromium/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaNotificationInfo.java new file mode 100644 index 00000000000..855ed9a50e2 --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaNotificationInfo.java @@ -0,0 +1,354 @@ +// 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.components.browser_ui.media; + +import android.content.Intent; +import android.graphics.Bitmap; +import android.text.TextUtils; + +import androidx.annotation.Nullable; + +import org.chromium.services.media_session.MediaMetadata; +import org.chromium.services.media_session.MediaPosition; + +import java.util.HashSet; +import java.util.Set; + +/** + * Exposes information about the current media notification to the external clients. + */ +public class MediaNotificationInfo { + // Bits defining various user actions supported by the media notification. + + /** + * If set, play/pause controls are shown and handled via notification UI and MediaSession. + */ + public static final int ACTION_PLAY_PAUSE = 1 << 0; + + /** + * If set, a stop button is shown and handled via the notification UI. + */ + public static final int ACTION_STOP = 1 << 1; + + /** + * If set, a user can swipe the notification away when it's paused. + * If notification swipe is not supported, it will behave like {@link #ACTION_STOP}. + */ + public static final int ACTION_SWIPEAWAY = 1 << 2; + + /** + * A value that represents an invalid ID. + */ + public static final int INVALID_ID = -1; + + /** + * Use this class to construct an instance of {@link MediaNotificationInfo}. + */ + public static final class Builder { + private MediaMetadata mMetadata; + private boolean mIsPaused; + private String mOrigin = ""; + private int mInstanceId = INVALID_ID; + private boolean mIsPrivate = true; + private int mNotificationSmallIcon; + private Bitmap mNotificationLargeIcon; + private int mDefaultNotificationLargeIcon; + private Bitmap mMediaSessionImage; + private int mActions = ACTION_PLAY_PAUSE | ACTION_SWIPEAWAY; + private int mId = INVALID_ID; + private Intent mContentIntent; + private MediaNotificationListener mListener; + private Set<Integer> mMediaSessionActions; + private @Nullable MediaPosition mMediaPosition; + + /** + * Initializes the builder with the default values. + */ + public Builder() {} + + public MediaNotificationInfo build() { + assert mMetadata != null; + assert mOrigin != null; + assert mListener != null; + + return new MediaNotificationInfo(mMetadata, mIsPaused, mOrigin, mInstanceId, mIsPrivate, + mNotificationSmallIcon, mNotificationLargeIcon, mDefaultNotificationLargeIcon, + mMediaSessionImage, mActions, mId, mContentIntent, mListener, + mMediaSessionActions, mMediaPosition); + } + + public Builder setMetadata(MediaMetadata metadata) { + mMetadata = metadata; + return this; + } + + public Builder setPaused(boolean isPaused) { + mIsPaused = isPaused; + return this; + } + + public Builder setOrigin(String origin) { + mOrigin = origin; + return this; + } + + public Builder setInstanceId(int instanceId) { + mInstanceId = instanceId; + return this; + } + + public Builder setPrivate(boolean isPrivate) { + mIsPrivate = isPrivate; + return this; + } + + public Builder setNotificationSmallIcon(int icon) { + mNotificationSmallIcon = icon; + return this; + } + + public Builder setNotificationLargeIcon(Bitmap icon) { + mNotificationLargeIcon = icon; + return this; + } + + public Builder setDefaultNotificationLargeIcon(int icon) { + mDefaultNotificationLargeIcon = icon; + return this; + } + + public Builder setMediaSessionImage(Bitmap image) { + mMediaSessionImage = image; + return this; + } + + public Builder setActions(int actions) { + mActions = actions; + return this; + } + + public Builder setId(int id) { + mId = id; + return this; + } + + public Builder setContentIntent(Intent intent) { + mContentIntent = intent; + return this; + } + + public Builder setListener(MediaNotificationListener listener) { + mListener = listener; + return this; + } + + public Builder setMediaSessionActions(Set<Integer> actions) { + mMediaSessionActions = actions; + return this; + } + + public Builder setMediaPosition(@Nullable MediaPosition position) { + mMediaPosition = position; + return this; + } + } + + /** + * The bitset defining user actions handled by the notification. + */ + private final int mActions; + + /** + * The metadata associated with the media. + */ + public final MediaMetadata metadata; + + /** + * The current state of the media, paused or not. + */ + public final boolean isPaused; + + /** + * The origin of the tab containing the media. + */ + public final String origin; + + /** + * An identifier that helps distinguish different instances of the same type of media + * notification. The {@link id} is shared by different MediaNotificationInfo instances for the + * same media type, but this identifier provides an extra layer of differentiation. In Chrome, + * for example, this corresponds to the source tab. + */ + public final int instanceId; + + /** + * Whether the media notification should be considered as private. + */ + public final boolean isPrivate; + + /** + * The id of the notification small icon from R.drawable. + */ + public final int notificationSmallIcon; + + /** + * The Bitmap resource used as the notification large icon. + */ + public final Bitmap notificationLargeIcon; + + /** + * The id of the default notification large icon from R.drawable. + */ + public final int defaultNotificationLargeIcon; + + /** + * The Bitmap resource used for Android MediaSession image, which will be used on lock screen + * and wearable devices. + */ + public final Bitmap mediaSessionImage; + + /** + * The id to use for the Android Notification. + */ + public final int id; + + /** + * The intent to send when the notification is selected. + */ + public final Intent contentIntent; + + /** + * The listener for the control events. + */ + public final MediaNotificationListener listener; + + /** + * The actions enabled in MediaSession. + */ + public final Set<Integer> mediaSessionActions; + + /** + * The current position of the media session. + */ + public final @Nullable MediaPosition mediaPosition; + + /** + * @return if play/pause actions are supported by this notification. + */ + public boolean supportsPlayPause() { + return (mActions & ACTION_PLAY_PAUSE) != 0; + } + + /** + * @return if stop action is supported by this notification. + */ + public boolean supportsStop() { + return (mActions & ACTION_STOP) != 0; + } + + /** + * @return if notification should be dismissable by swiping it away when paused. + */ + public boolean supportsSwipeAway() { + return (mActions & ACTION_SWIPEAWAY) != 0; + } + + /** + * Create a new MediaNotificationInfo. + * @param metadata The metadata associated with the media. + * @param isPaused The current state of the media, paused or not. + * @param origin The origin of the tab containing the media. + * @param instanceId The id of the tab containing the media. + * @param isPrivate Whether the media notification should be considered as private. + * @param notificationSmallIcon The small icon used in the notification. + * @param notificationLargeIcon The large icon used in the notification. + * @param defaultNotificationLargeIcon The fallback large icon when |notificationLargeIcon| is + * improper to use. + * @param mediaSessionImage The artwork image to be used in Android MediaSession. + * @param actions The actions supported in this notification. + * @param id The id of this notification, which is used for distinguishing media playback, cast + * and media remote. + * @param contentIntent The intent to send when the notification is selected. + * @param listener The listener for the control events. + * @param mediaSessionActions The actions supported by the page. + * @param mediaPosition The current position of the media. + */ + private MediaNotificationInfo(MediaMetadata metadata, boolean isPaused, String origin, + int instanceId, boolean isPrivate, int notificationSmallIcon, + Bitmap notificationLargeIcon, int defaultNotificationLargeIcon, + Bitmap mediaSessionImage, int actions, int id, Intent contentIntent, + MediaNotificationListener listener, Set<Integer> mediaSessionActions, + @Nullable MediaPosition mediaPosition) { + this.metadata = metadata; + this.isPaused = isPaused; + this.origin = origin; + assert instanceId != INVALID_ID; + this.instanceId = instanceId; + this.isPrivate = isPrivate; + this.notificationSmallIcon = notificationSmallIcon; + this.notificationLargeIcon = notificationLargeIcon; + this.defaultNotificationLargeIcon = defaultNotificationLargeIcon; + this.mediaSessionImage = mediaSessionImage; + this.mActions = actions; + assert id != INVALID_ID; + this.id = id; + this.contentIntent = contentIntent; + this.listener = listener; + this.mediaSessionActions = (mediaSessionActions != null) + ? new HashSet<Integer>(mediaSessionActions) + : new HashSet<Integer>(); + this.mediaPosition = mediaPosition; + } + + @Override + @SuppressWarnings("ReferenceEquality") + public boolean equals(Object obj) { + if (obj == this) return true; + if (!(obj instanceof MediaNotificationInfo)) return false; + + MediaNotificationInfo other = (MediaNotificationInfo) obj; + return isPaused == other.isPaused && isPrivate == other.isPrivate + && instanceId == other.instanceId + && notificationSmallIcon == other.notificationSmallIcon + && (notificationLargeIcon == other.notificationLargeIcon + || (notificationLargeIcon != null + && notificationLargeIcon.sameAs(other.notificationLargeIcon))) + && defaultNotificationLargeIcon == other.defaultNotificationLargeIcon + && mediaSessionImage == other.mediaSessionImage && mActions == other.mActions + && id == other.id + && (metadata == other.metadata + || (metadata != null && metadata.equals(other.metadata))) + && TextUtils.equals(origin, other.origin) + && (contentIntent == other.contentIntent + || (contentIntent != null && contentIntent.equals(other.contentIntent))) + && (listener == other.listener + || (listener != null && listener.equals(other.listener))) + && (mediaSessionActions == other.mediaSessionActions + || (mediaSessionActions != null + && mediaSessionActions.equals(other.mediaSessionActions))) + && mediaPosition == other.mediaPosition; + } + + @Override + public int hashCode() { + int result = isPaused ? 1 : 0; + result = 31 * result + (isPrivate ? 1 : 0); + result = 31 * result + (metadata == null ? 0 : metadata.hashCode()); + result = 31 * result + (origin == null ? 0 : origin.hashCode()); + result = 31 * result + (contentIntent == null ? 0 : contentIntent.hashCode()); + result = 31 * result + instanceId; + result = 31 * result + notificationSmallIcon; + result = 31 * result + + (notificationLargeIcon == null ? 0 : notificationLargeIcon.hashCode()); + result = 31 * result + defaultNotificationLargeIcon; + result = 31 * result + (mediaSessionImage == null ? 0 : mediaSessionImage.hashCode()); + result = 31 * result + mActions; + result = 31 * result + id; + result = 31 * result + listener.hashCode(); + result = 31 * result + mediaSessionActions.hashCode(); + result = 31 * result + mediaPosition.hashCode(); + return result; + } +} diff --git a/chromium/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaNotificationListener.java b/chromium/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaNotificationListener.java new file mode 100644 index 00000000000..f4ae70e4e24 --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaNotificationListener.java @@ -0,0 +1,57 @@ +// 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.components.browser_ui.media; + +/** + * Interface for classes that need to be notified about media events. + */ +public interface MediaNotificationListener { + /** + * The media action was caused by direct interaction with the notification. + */ + public static final int ACTION_SOURCE_MEDIA_NOTIFICATION = 1000; + + /** + * The media action was received via the MediaSession Android API, e.g. a headset, a watch, etc. + */ + public static final int ACTION_SOURCE_MEDIA_SESSION = 1001; + + /** + * The media action was received by unplugging the headset, + * which broadcasts an ACTION_AUDIO_BECOMING_NOISY intent. + */ + public static final int ACTION_SOURCE_HEADSET_UNPLUG = 1002; + + /** + * Called when the user wants to resume the playback. + * @param actionSource The source the listener got the action from. + */ + void onPlay(int actionSource); + + /** + * Called when the user wants to pause the playback. + * @param actionSource The source the listener got the action from. + */ + void onPause(int actionSource); + + /** + * Called when the user wants to stop the playback. + * @param actionSource The source the listener got the action from. + */ + void onStop(int actionSource); + + /** + * Called when the user performed one of the media actions (like fast forward or next track) + * supported by MediaSession. + * @param action The kind of the initated action. + */ + void onMediaSessionAction(int action); + + /** + * Called when the user performed a seek action through Media Session. + * @param action The position to seek to in ms. + */ + void onMediaSessionSeekTo(long pos); +} diff --git a/chromium/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaNotificationUma.java b/chromium/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaNotificationUma.java new file mode 100644 index 00000000000..83c25162906 --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaNotificationUma.java @@ -0,0 +1,47 @@ +// Copyright 2016 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.components.browser_ui.media; + +import android.content.Intent; + +import androidx.annotation.IntDef; + +import org.chromium.base.metrics.RecordHistogram; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Helper class to record which kind of media notifications does the user click to go back to + * Chrome. + */ +public class MediaNotificationUma { + @IntDef({Source.INVALID, Source.MEDIA, Source.PRESENTATION, Source.MEDIA_FLING}) + @Retention(RetentionPolicy.SOURCE) + public @interface Source { + int INVALID = -1; + int MEDIA = 0; + int PRESENTATION = 1; + int MEDIA_FLING = 2; + int NUM_ENTRIES = 3; + } + + public static final String INTENT_EXTRA_NAME = + "org.chromium.chrome.browser.metrics.MediaNotificationUma.EXTRA_CLICK_SOURCE"; + + /** + * Record the UMA as specified by {@link intent}. The {@link intent} should contain intent extra + * of name {@link INTENT_EXTRA_NAME} indicating the type. + * @param intent The intent starting the activity. + */ + public static void recordClickSource(Intent intent) { + if (intent == null) return; + @Source + int source = intent.getIntExtra(INTENT_EXTRA_NAME, Source.INVALID); + if (source == Source.INVALID || source >= Source.NUM_ENTRIES) return; + RecordHistogram.recordEnumeratedHistogram( + "Media.Notification.Click", source, Source.NUM_ENTRIES); + } +} diff --git a/chromium/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaSessionHelper.java b/chromium/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaSessionHelper.java new file mode 100644 index 00000000000..7c9422e2248 --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaSessionHelper.java @@ -0,0 +1,573 @@ +// Copyright 2020 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.components.browser_ui.media; + +import android.app.Activity; +import android.content.Intent; +import android.graphics.Bitmap; +import android.media.AudioManager; +import android.os.Build; +import android.os.Handler; +import android.text.TextUtils; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; + +import org.chromium.base.SysUtils; +import org.chromium.components.url_formatter.UrlFormatter; +import org.chromium.content_public.browser.MediaSession; +import org.chromium.content_public.browser.MediaSessionObserver; +import org.chromium.content_public.browser.NavigationHandle; +import org.chromium.content_public.browser.WebContents; +import org.chromium.content_public.browser.WebContentsObserver; +import org.chromium.media_session.mojom.MediaSessionAction; +import org.chromium.services.media_session.MediaImage; +import org.chromium.services.media_session.MediaMetadata; +import org.chromium.services.media_session.MediaPosition; +import org.chromium.ui.base.WindowAndroid; + +import java.util.List; +import java.util.Set; + +/** + * Glue code that relays events from the {@link org.chromium.content.browser.MediaSession} for a + * WebContents to a delegate (ultimately, to {@link MediaNotificationController}). + */ +public class MediaSessionHelper implements MediaImageCallback { + private static final String TAG = "MediaSession"; + + private static final String UNICODE_PLAY_CHARACTER = "\u25B6"; + @VisibleForTesting + public static final int HIDE_NOTIFICATION_DELAY_MILLIS = 2500; + + private Delegate mDelegate; + private WebContents mWebContents; + @VisibleForTesting + public WebContentsObserver mWebContentsObserver; + @VisibleForTesting + public MediaSessionObserver mMediaSessionObserver; + private MediaImageManager mMediaImageManager; + private Bitmap mPageMediaImage; + @VisibleForTesting + public Bitmap mFavicon; + private Bitmap mCurrentMediaImage; + private String mOrigin; + private int mPreviousVolumeControlStream = AudioManager.USE_DEFAULT_STREAM_TYPE; + @VisibleForTesting + public MediaNotificationInfo.Builder mNotificationInfoBuilder; + // The fallback title if |mPageMetadata| is null or its title is empty. + private String mFallbackTitle; + // Set to true if favicon update callback was called at least once. + private boolean mMaybeHasFavicon; + // The metadata set by the page. + private MediaMetadata mPageMetadata; + // The currently showing metadata. + private MediaMetadata mCurrentMetadata; + private Set<Integer> mMediaSessionActions; + private @Nullable MediaPosition mMediaPosition; + private Handler mHandler; + // The delayed task to hide notification. Hiding notification can be immediate or delayed. + // Delayed hiding will schedule this delayed task to |mHandler|. The task will be canceled when + // showing or immediate hiding. + private Runnable mHideNotificationDelayedTask; + + // Used to override the MediaSession object get from WebContents. This is to work around the + // static getter {@link MediaSession#fromWebContents()}. + @VisibleForTesting + public static MediaSession sOverriddenMediaSession; + + private MediaNotificationListener mControlsListener = new MediaNotificationListener() { + @Override + public void onPlay(int actionSource) { + if (isNotificationHidingOrHidden()) return; + + MediaSessionUma.recordPlay( + MediaSessionHelper.convertMediaActionSourceToUMA(actionSource)); + + if (mMediaSessionObserver.getMediaSession() == null) return; + + mMediaSessionObserver.getMediaSession().resume(); + } + + @Override + public void onPause(int actionSource) { + if (isNotificationHidingOrHidden()) return; + + MediaSessionUma.recordPause( + MediaSessionHelper.convertMediaActionSourceToUMA(actionSource)); + + if (mMediaSessionObserver.getMediaSession() == null) return; + + mMediaSessionObserver.getMediaSession().suspend(); + } + + @Override + public void onStop(int actionSource) { + if (isNotificationHidingOrHidden()) return; + + MediaSessionUma.recordStop( + MediaSessionHelper.convertMediaActionSourceToUMA(actionSource)); + + if (mMediaSessionObserver.getMediaSession() != null) { + mMediaSessionObserver.getMediaSession().stop(); + } + } + + @Override + public void onMediaSessionAction(int action) { + if (!MediaSessionAction.isKnownValue(action)) return; + if (mMediaSessionObserver != null) { + mMediaSessionObserver.getMediaSession().didReceiveAction(action); + } + } + + @Override + public void onMediaSessionSeekTo(long pos) { + if (mMediaSessionObserver == null) return; + mMediaSessionObserver.getMediaSession().seekTo(pos); + } + }; + + private void hideNotificationDelayed() { + if (mWebContentsObserver == null) return; + if (mHideNotificationDelayedTask != null) return; + + mHideNotificationDelayedTask = new Runnable() { + @Override + public void run() { + mHideNotificationDelayedTask = null; + hideNotificationInternal(); + } + }; + mHandler.postDelayed(mHideNotificationDelayedTask, HIDE_NOTIFICATION_DELAY_MILLIS); + + mNotificationInfoBuilder = null; + mFavicon = null; + } + + private void hideNotificationImmediately() { + if (mWebContentsObserver == null) return; + if (mHideNotificationDelayedTask != null) { + mHandler.removeCallbacks(mHideNotificationDelayedTask); + mHideNotificationDelayedTask = null; + } + + hideNotificationInternal(); + mNotificationInfoBuilder = null; + } + + /** + * This method performs the common steps for hiding the notification. It should only be called + * by {@link #hideNotificationDelayed()} and {@link #hideNotificationImmediately()}. + */ + private void hideNotificationInternal() { + mDelegate.hideMediaNotification(); + Activity activity = getActivity(); + if (activity != null) { + activity.setVolumeControlStream(mPreviousVolumeControlStream); + } + } + + private void showNotification() { + assert mNotificationInfoBuilder != null; + if (mHideNotificationDelayedTask != null) { + mHandler.removeCallbacks(mHideNotificationDelayedTask); + mHideNotificationDelayedTask = null; + } + mDelegate.showMediaNotification(mNotificationInfoBuilder.build()); + } + + private MediaSessionObserver createMediaSessionObserver(MediaSession mediaSession) { + return new MediaSessionObserver(mediaSession) { + @Override + public void mediaSessionDestroyed() { + hideNotificationImmediately(); + cleanupMediaSessionObserver(); + } + + @Override + public void mediaSessionStateChanged(boolean isControllable, boolean isPaused) { + if (!isControllable) { + hideNotificationDelayed(); + return; + } + + Intent contentIntent = mDelegate.createBringTabToFrontIntent(); + if (contentIntent != null) { + contentIntent.putExtra(MediaNotificationUma.INTENT_EXTRA_NAME, + MediaNotificationUma.Source.MEDIA); + } + + if (mFallbackTitle == null) mFallbackTitle = sanitizeMediaTitle(mOrigin); + + mCurrentMetadata = getMetadata(); + mCurrentMediaImage = getCachedNotificationImage(); + mNotificationInfoBuilder = + mDelegate.createMediaNotificationInfoBuilder() + .setMetadata(mCurrentMetadata) + .setPaused(isPaused) + .setOrigin(mOrigin) + .setPrivate(mWebContents.isIncognito()) + .setNotificationSmallIcon(R.drawable.audio_playing) + .setNotificationLargeIcon(mCurrentMediaImage) + .setMediaSessionImage(mPageMediaImage) + .setActions(MediaNotificationInfo.ACTION_PLAY_PAUSE + | MediaNotificationInfo.ACTION_SWIPEAWAY) + .setContentIntent(contentIntent) + .setListener(mControlsListener) + .setMediaSessionActions(mMediaSessionActions) + .setMediaPosition(mMediaPosition); + + // Show a default icon in incognito contents, as they don't show the media icon. + // Also show a default icon if we won't get a favicon from {@link mDelegate}. If the + // delegate will pass a favicon later, show nothing for now; we expect the favicon + // to arrive quickly. + if (mWebContents.isIncognito() + || (mCurrentMediaImage == null && !fetchLargeFaviconImage())) { + mNotificationInfoBuilder.setDefaultNotificationLargeIcon( + R.drawable.audio_playing_square); + } + showNotification(); + Activity activity = getActivity(); + if (activity != null) { + activity.setVolumeControlStream(AudioManager.STREAM_MUSIC); + } + } + + @Override + public void mediaSessionMetadataChanged(MediaMetadata metadata) { + mPageMetadata = metadata; + updateNotificationMetadata(); + } + + @Override + public void mediaSessionActionsChanged(Set<Integer> actions) { + mMediaSessionActions = actions; + updateNotificationActions(); + } + + @Override + public void mediaSessionArtworkChanged(List<MediaImage> images) { + mMediaImageManager.downloadImage(images, MediaSessionHelper.this); + updateNotificationMetadata(); + } + + @Override + public void mediaSessionPositionChanged(@Nullable MediaPosition position) { + mMediaPosition = position; + updateNotificationPosition(); + } + }; + } + + public void setWebContents(@NonNull WebContents webContents) { + if (mWebContents == webContents) return; + + mWebContents = webContents; + + if (mWebContentsObserver != null) mWebContentsObserver.destroy(); + mWebContentsObserver = new WebContentsObserver(webContents) { + @Override + public void didFinishNavigation(NavigationHandle navigation) { + if (!navigation.hasCommitted() || !navigation.isInMainFrame() + || navigation.isSameDocument()) { + return; + } + + mOrigin = UrlFormatter.formatUrlForDisplayOmitSchemeOmitTrivialSubdomains( + webContents.getVisibleUrl().getOrigin().getSpec()); + mFavicon = null; + mPageMediaImage = null; + mPageMetadata = null; + // |mCurrentMetadata| selects either |mPageMetadata| or |mFallbackTitle|. As + // there is no guarantee {@link #titleWasSet()} will be called before or + // after this method, |mFallbackTitle| is not reset in this callback, i.e. + // relying solely on + // {@link #titleWasSet()}. The following assignment is to keep + // |mCurrentMetadata| up to date as |mPageMetadata| may have changed. + mCurrentMetadata = getMetadata(); + mMediaSessionActions = null; + + if (isNotificationHidingOrHidden()) return; + + mNotificationInfoBuilder.setOrigin(mOrigin); + mNotificationInfoBuilder.setNotificationLargeIcon(mFavicon); + mNotificationInfoBuilder.setMediaSessionImage(mPageMediaImage); + mNotificationInfoBuilder.setMetadata(mCurrentMetadata); + mNotificationInfoBuilder.setMediaSessionActions(mMediaSessionActions); + showNotification(); + } + + @Override + public void titleWasSet(String title) { + String newFallbackTitle = sanitizeMediaTitle(title); + if (!TextUtils.equals(mFallbackTitle, newFallbackTitle)) { + mFallbackTitle = newFallbackTitle; + updateNotificationMetadata(); + } + } + + @Override + public void wasShown() { + mDelegate.activateAndroidMediaSession(); + } + }; + + MediaSession mediaSession = getMediaSession(webContents); + if (mMediaSessionObserver != null + && mediaSession == mMediaSessionObserver.getMediaSession()) { + return; + } + + cleanupMediaSessionObserver(); + mMediaImageManager.setWebContents(webContents); + if (mediaSession != null) { + mMediaSessionObserver = createMediaSessionObserver(mediaSession); + } + } + + private void cleanupMediaSessionObserver() { + if (mMediaSessionObserver == null) return; + mMediaSessionObserver.stopObserving(); + mMediaSessionObserver = null; + mMediaSessionActions = null; + } + + /** An interface for dispatching embedder-specific behavior. */ + public interface Delegate { + /** Returns an intent that brings the associated web contents to the front. */ + Intent createBringTabToFrontIntent(); + + /** + * Called to asynchronously fetch a larger favicon image. + * + * Normal, smaller favicons are passed in automatically. This call triggers lookup of a + * larger icon, which will also be passed in via {@link updateFavicon()}, or not at all if + * this method returns false. + * @return true if the favicon will be updated. + */ + boolean fetchLargeFaviconImage(); + + /** + * Creates a {@link MediaNotificationInfo.Builder} with basic embedder-specific + * initialization. + */ + public MediaNotificationInfo.Builder createMediaNotificationInfoBuilder(); + + /** Shows a notification with the given metadata. */ + void showMediaNotification(MediaNotificationInfo notificationInfo); + + /** Hides the active notification. */ + void hideMediaNotification(); + + /** Activates the Android MediaSession. */ + void activateAndroidMediaSession(); + } + + public MediaSessionHelper(@NonNull WebContents webContents, @NonNull Delegate delegate) { + mDelegate = delegate; + mMediaImageManager = + new MediaImageManager(MediaNotificationImageUtils.MINIMAL_MEDIA_IMAGE_SIZE_PX, + MediaNotificationImageUtils.getIdealMediaImageSize()); + mHandler = new Handler(); + setWebContents(webContents); + + Activity activity = getActivity(); + if (activity != null) { + mPreviousVolumeControlStream = activity.getVolumeControlStream(); + } + } + + /** + * Called when this object should no longer manage a media session because owning code no longer + * requires it. + */ + public void destroy() { + cleanupMediaSessionObserver(); + hideNotificationImmediately(); + if (mWebContentsObserver != null) mWebContentsObserver.destroy(); + mWebContentsObserver = null; + } + + /** + * Removes all the leading/trailing white spaces and the quite common unicode play character. + * It improves the visibility of the title in the notification. + * + * @param title The original tab title, e.g. " ▶ Foo - Bar " + * @return The sanitized tab title, e.g. "Foo - Bar" + */ + private String sanitizeMediaTitle(String title) { + title = title.trim(); + return title.startsWith(UNICODE_PLAY_CHARACTER) ? title.substring(1).trim() : title; + } + + /** + * Converts the {@link MediaNotificationListener} action source enum into the + * {@link MediaSessionUma} one to ensure matching the histogram values. + * @param source the source id, must be one of the ACTION_SOURCE_* constants defined in the + * {@link MediaNotificationListener} interface. + * @return the corresponding histogram value. + */ + public static @MediaSessionUma.MediaSessionActionSource int convertMediaActionSourceToUMA( + int source) { + if (source == MediaNotificationListener.ACTION_SOURCE_MEDIA_NOTIFICATION) { + return MediaSessionUma.MediaSessionActionSource.MEDIA_NOTIFICATION; + } else if (source == MediaNotificationListener.ACTION_SOURCE_MEDIA_SESSION) { + return MediaSessionUma.MediaSessionActionSource.MEDIA_SESSION; + } else if (source == MediaNotificationListener.ACTION_SOURCE_HEADSET_UNPLUG) { + return MediaSessionUma.MediaSessionActionSource.HEADSET_UNPLUG; + } + + assert false; + return MediaSessionUma.MediaSessionActionSource.NUM_ENTRIES; + } + + private Activity getActivity() { + assert mWebContents != null; + WindowAndroid windowAndroid = mWebContents.getTopLevelNativeWindow(); + if (windowAndroid == null) return null; + + return windowAndroid.getActivity().get(); + } + + /** Returns true if a large favicon might be found. */ + private boolean fetchLargeFaviconImage() { + // The page does not have a favicon yet to fetch since onFaviconUpdated was never called. + // Don't waste time trying to find it. + if (!mMaybeHasFavicon) return false; + + return mDelegate.fetchLargeFaviconImage(); + } + + /** + * Updates the best favicon if the given icon is better and the favicon is shown in + * notification. + */ + public void updateFavicon(Bitmap icon) { + if (icon == null) return; + + mMaybeHasFavicon = true; + + // Store the favicon only if notification is being shown. Otherwise the favicon is + // obtained from large icon bridge when needed. + if (isNotificationHidingOrHidden() || mPageMediaImage != null) return; + + // Disable favicons in notifications for low memory devices on O + // where the notification icon is optional. + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && SysUtils.isLowEndDevice()) return; + + if (!MediaNotificationImageUtils.isBitmapSuitableAsMediaImage(icon)) return; + if (mFavicon != null + && (icon.getWidth() < mFavicon.getWidth() + || icon.getHeight() < mFavicon.getHeight())) { + return; + } + mFavicon = MediaNotificationImageUtils.downscaleIconToIdealSize(icon); + updateNotificationImage(mFavicon); + } + + /** Sets an icon which will preferentially be used in place of a smaller favicon. */ + public void setLargeIcon(Bitmap icon) { + if (isNotificationHidingOrHidden()) return; + + if (icon == null) { + // If we do not have any favicon then make sure we show default sound icon. This + // icon is used by notification manager only if we do not show any icon. + mNotificationInfoBuilder.setDefaultNotificationLargeIcon( + R.drawable.audio_playing_square); + showNotification(); + } else { + updateFavicon(icon); + } + } + + /** + * Updates the metadata in media notification. This method should be called whenever + * |mPageMetadata| or |mFallbackTitle| is changed. + */ + private void updateNotificationMetadata() { + if (isNotificationHidingOrHidden()) return; + + MediaMetadata newMetadata = getMetadata(); + if (mCurrentMetadata.equals(newMetadata)) return; + + mCurrentMetadata = newMetadata; + mNotificationInfoBuilder.setMetadata(mCurrentMetadata); + showNotification(); + } + + /** + * @return The up-to-date MediaSession metadata. Returns the cached object like |mPageMetadata| + * or |mCurrentMetadata| if it reflects the current state. Otherwise will return a new + * {@link MediaMetadata} object. + */ + private MediaMetadata getMetadata() { + String title = mFallbackTitle; + String artist = ""; + String album = ""; + if (mPageMetadata != null) { + if (!TextUtils.isEmpty(mPageMetadata.getTitle())) return mPageMetadata; + + artist = mPageMetadata.getArtist(); + album = mPageMetadata.getAlbum(); + } + + if (mCurrentMetadata != null && TextUtils.equals(title, mCurrentMetadata.getTitle()) + && TextUtils.equals(artist, mCurrentMetadata.getArtist()) + && TextUtils.equals(album, mCurrentMetadata.getAlbum())) { + return mCurrentMetadata; + } + + return new MediaMetadata(title, artist, album); + } + + private void updateNotificationActions() { + if (isNotificationHidingOrHidden()) return; + + mNotificationInfoBuilder.setMediaSessionActions(mMediaSessionActions); + showNotification(); + } + + private void updateNotificationPosition() { + if (isNotificationHidingOrHidden()) return; + + mNotificationInfoBuilder.setMediaPosition(mMediaPosition); + showNotification(); + } + + @Override + public void onImageDownloaded(Bitmap image) { + mPageMediaImage = MediaNotificationImageUtils.downscaleIconToIdealSize(image); + mFavicon = null; + updateNotificationImage(mPageMediaImage); + } + + private void updateNotificationImage(Bitmap newMediaImage) { + if (mCurrentMediaImage == newMediaImage) return; + + mCurrentMediaImage = newMediaImage; + + if (isNotificationHidingOrHidden()) return; + mNotificationInfoBuilder.setNotificationLargeIcon(mCurrentMediaImage); + mNotificationInfoBuilder.setMediaSessionImage(mPageMediaImage); + showNotification(); + } + + private Bitmap getCachedNotificationImage() { + if (mPageMediaImage != null) return mPageMediaImage; + if (mFavicon != null) return mFavicon; + return null; + } + + private boolean isNotificationHidingOrHidden() { + return mNotificationInfoBuilder == null; + } + + private MediaSession getMediaSession(WebContents contents) { + return (sOverriddenMediaSession != null) ? sOverriddenMediaSession + : MediaSession.fromWebContents(contents); + } +} diff --git a/chromium/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaSessionUma.java b/chromium/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaSessionUma.java new file mode 100644 index 00000000000..58f489fc1e8 --- /dev/null +++ b/chromium/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaSessionUma.java @@ -0,0 +1,42 @@ +// 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.components.browser_ui.media; + +import androidx.annotation.IntDef; + +import org.chromium.base.metrics.RecordHistogram; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** Centralizes UMA data collection for Android-specific MediaSession features. */ +public class MediaSessionUma { + // MediaSessionAction defined in tools/metrics/histograms/histograms.xml. + @IntDef({MediaSessionActionSource.MEDIA_NOTIFICATION, MediaSessionActionSource.MEDIA_SESSION, + MediaSessionActionSource.HEADSET_UNPLUG}) + @Retention(RetentionPolicy.SOURCE) + public @interface MediaSessionActionSource { + int MEDIA_NOTIFICATION = 0; + int MEDIA_SESSION = 1; + int HEADSET_UNPLUG = 2; + + int NUM_ENTRIES = 3; + } + + public static void recordPlay(@MediaSessionActionSource int action) { + RecordHistogram.recordEnumeratedHistogram( + "Media.Session.Play", action, MediaSessionActionSource.NUM_ENTRIES); + } + + public static void recordPause(@MediaSessionActionSource int action) { + RecordHistogram.recordEnumeratedHistogram( + "Media.Session.Pause", action, MediaSessionActionSource.NUM_ENTRIES); + } + + public static void recordStop(@MediaSessionActionSource int action) { + RecordHistogram.recordEnumeratedHistogram( + "Media.Session.Stop", action, MediaSessionActionSource.NUM_ENTRIES); + } +} diff --git a/chromium/components/browser_ui/modaldialog/android/BUILD.gn b/chromium/components/browser_ui/modaldialog/android/BUILD.gn index e2f4d4f4829..88ddb752e03 100644 --- a/chromium/components/browser_ui/modaldialog/android/BUILD.gn +++ b/chromium/components/browser_ui/modaldialog/android/BUILD.gn @@ -56,9 +56,9 @@ android_library("javatests") { "//base:base_java_test_support", "//content/public/test/android:content_java_test_support", "//third_party/android_deps:androidx_core_core_java", + "//third_party/android_deps:espresso_java", "//third_party/android_support_test_runner:rules_java", "//third_party/android_support_test_runner:runner_java", - "//third_party/espresso:espresso_all_java", "//third_party/hamcrest:hamcrest_java", "//third_party/junit:junit", "//ui/android:ui_java", diff --git a/chromium/components/browser_ui/modaldialog/android/java/src/org/chromium/components/browser_ui/modaldialog/AppModalPresenterTest.java b/chromium/components/browser_ui/modaldialog/android/java/src/org/chromium/components/browser_ui/modaldialog/AppModalPresenterTest.java index 291cd1a6062..89e3e1cc702 100644 --- a/chromium/components/browser_ui/modaldialog/android/java/src/org/chromium/components/browser_ui/modaldialog/AppModalPresenterTest.java +++ b/chromium/components/browser_ui/modaldialog/android/java/src/org/chromium/components/browser_ui/modaldialog/AppModalPresenterTest.java @@ -4,11 +4,11 @@ package org.chromium.components.browser_ui.modaldialog; -import static android.support.test.espresso.Espresso.onView; -import static android.support.test.espresso.assertion.ViewAssertions.doesNotExist; -import static android.support.test.espresso.assertion.ViewAssertions.matches; -import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; -import static android.support.test.espresso.matcher.ViewMatchers.withText; +import static androidx.test.espresso.Espresso.onView; +import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist; +import static androidx.test.espresso.assertion.ViewAssertions.matches; +import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; +import static androidx.test.espresso.matcher.ViewMatchers.withText; import static org.chromium.components.browser_ui.modaldialog.ModalDialogTestUtils.checkCurrentPresenter; import static org.chromium.components.browser_ui.modaldialog.ModalDialogTestUtils.checkDialogDismissalCause; @@ -16,8 +16,8 @@ import static org.chromium.components.browser_ui.modaldialog.ModalDialogTestUtil import static org.chromium.components.browser_ui.modaldialog.ModalDialogTestUtils.createDialog; import static org.chromium.components.browser_ui.modaldialog.ModalDialogTestUtils.showDialog; -import android.support.test.espresso.Espresso; -import android.support.test.filters.SmallTest; +import androidx.test.espresso.Espresso; +import androidx.test.filters.SmallTest; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/chromium/components/browser_ui/modaldialog/android/java/src/org/chromium/components/browser_ui/modaldialog/ModalDialogViewTest.java b/chromium/components/browser_ui/modaldialog/android/java/src/org/chromium/components/browser_ui/modaldialog/ModalDialogViewTest.java index ffa19f5974b..225470cf110 100644 --- a/chromium/components/browser_ui/modaldialog/android/java/src/org/chromium/components/browser_ui/modaldialog/ModalDialogViewTest.java +++ b/chromium/components/browser_ui/modaldialog/android/java/src/org/chromium/components/browser_ui/modaldialog/ModalDialogViewTest.java @@ -4,29 +4,31 @@ package org.chromium.components.browser_ui.modaldialog; -import static android.support.test.espresso.Espresso.onView; -import static android.support.test.espresso.assertion.ViewAssertions.matches; -import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; -import static android.support.test.espresso.matcher.ViewMatchers.isEnabled; -import static android.support.test.espresso.matcher.ViewMatchers.withChild; -import static android.support.test.espresso.matcher.ViewMatchers.withId; -import static android.support.test.espresso.matcher.ViewMatchers.withParent; -import static android.support.test.espresso.matcher.ViewMatchers.withText; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; +import static androidx.test.espresso.Espresso.onView; +import static androidx.test.espresso.assertion.ViewAssertions.matches; +import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; +import static androidx.test.espresso.matcher.ViewMatchers.isEnabled; +import static androidx.test.espresso.matcher.ViewMatchers.withChild; +import static androidx.test.espresso.matcher.ViewMatchers.withId; +import static androidx.test.espresso.matcher.ViewMatchers.withParent; +import static androidx.test.espresso.matcher.ViewMatchers.withText; + import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.not; import android.app.Activity; import android.content.res.Resources; -import android.support.test.filters.MediumTest; import android.view.ContextThemeWrapper; import android.view.LayoutInflater; import android.view.View; import android.widget.FrameLayout; import android.widget.TextView; +import androidx.test.filters.MediumTest; + import org.hamcrest.Description; import org.hamcrest.Matcher; import org.hamcrest.TypeSafeMatcher; diff --git a/chromium/components/browser_ui/notifications/android/BUILD.gn b/chromium/components/browser_ui/notifications/android/BUILD.gn index 78dcfecfc03..220f0f987cd 100644 --- a/chromium/components/browser_ui/notifications/android/BUILD.gn +++ b/chromium/components/browser_ui/notifications/android/BUILD.gn @@ -8,6 +8,7 @@ android_library("java") { sources = [ "java/src/org/chromium/components/browser_ui/notifications/ChromeNotification.java", "java/src/org/chromium/components/browser_ui/notifications/ChromeNotificationBuilder.java", + "java/src/org/chromium/components/browser_ui/notifications/ForegroundServiceUtils.java", "java/src/org/chromium/components/browser_ui/notifications/NotificationBuilder.java", "java/src/org/chromium/components/browser_ui/notifications/NotificationCompatBuilder.java", "java/src/org/chromium/components/browser_ui/notifications/NotificationManagerProxy.java", diff --git a/chromium/components/browser_ui/notifications/android/java/src/org/chromium/components/browser_ui/notifications/ForegroundServiceUtils.java b/chromium/components/browser_ui/notifications/android/java/src/org/chromium/components/browser_ui/notifications/ForegroundServiceUtils.java new file mode 100644 index 00000000000..ca6227ee7b0 --- /dev/null +++ b/chromium/components/browser_ui/notifications/android/java/src/org/chromium/components/browser_ui/notifications/ForegroundServiceUtils.java @@ -0,0 +1,91 @@ +// Copyright 2019 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.components.browser_ui.notifications; + +import android.app.Notification; +import android.app.Service; +import android.content.Intent; +import android.os.Build; + +import androidx.annotation.VisibleForTesting; +import androidx.core.app.ServiceCompat; +import androidx.core.content.ContextCompat; + +import org.chromium.base.ContextUtils; +import org.chromium.base.Log; + +/** + * Utility functions that call into Android foreground service related API, and provides + * compatibility for older Android versions and work around for Android API bugs. + */ +public class ForegroundServiceUtils { + private static final String TAG = "ForegroundService"; + private ForegroundServiceUtils() {} + + /** + * Gets the singleton instance of ForegroundServiceUtils. + */ + public static ForegroundServiceUtils getInstance() { + return ForegroundServiceUtils.LazyHolder.sInstance; + } + + /** + * Sets a mocked instance for testing. + */ + @VisibleForTesting + public static void setInstanceForTesting(ForegroundServiceUtils instance) { + ForegroundServiceUtils.LazyHolder.sInstance = instance; + } + + private static class LazyHolder { + private static ForegroundServiceUtils sInstance = new ForegroundServiceUtils(); + } + + /** + * Starts a service from {@code intent} with the expectation that it will make itself a + * foreground service with {@link android.app.Service#startForeground(int, Notification)}. + * + * @param intent The {@link Intent} to fire to start the service. + */ + public void startForegroundService(Intent intent) { + ContextCompat.startForegroundService(ContextUtils.getApplicationContext(), intent); + } + + /** + * Upgrades a service from background to foreground after calling + * {@link #startForegroundService(Intent)}. + * @param service The service to be foreground. + * @param id The notification id. + * @param notification The notification attached to the foreground service. + * @param foregroundServiceType The type of foreground service. Must be a subset of the + * foreground service types defined in AndroidManifest.xml. + * Use 0 if no foregroundServiceType attribute is defined. + */ + public void startForeground( + Service service, int id, Notification notification, int foregroundServiceType) { + // If android fail to build the notification, do nothing. + if (notification == null) return; + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + service.startForeground(id, notification, foregroundServiceType); + } else { + service.startForeground(id, notification); + } + } + + /** + * Stops the foreground service. See {@link ServiceCompat#stopForeground(Service, int)}. + * @param service The foreground service to stop. + * @param flags The flags to stop foreground service. + */ + public void stopForeground(Service service, int flags) { + // OnePlus devices may throw NullPointerException, see https://crbug.com/992347. + try { + ServiceCompat.stopForeground(service, flags); + } catch (NullPointerException e) { + Log.e(TAG, "Failed to stop foreground service, ", e); + } + } +} diff --git a/chromium/components/browser_ui/settings/android/BUILD.gn b/chromium/components/browser_ui/settings/android/BUILD.gn index 806560d5d19..3f907927a63 100644 --- a/chromium/components/browser_ui/settings/android/BUILD.gn +++ b/chromium/components/browser_ui/settings/android/BUILD.gn @@ -16,6 +16,7 @@ android_library("java") { "widget/java/src/org/chromium/components/browser_ui/settings/ChromeImageViewPreference.java", "widget/java/src/org/chromium/components/browser_ui/settings/ChromeSwitchPreference.java", "widget/java/src/org/chromium/components/browser_ui/settings/ExpandablePreferenceGroup.java", + "widget/java/src/org/chromium/components/browser_ui/settings/IconPreference.java", "widget/java/src/org/chromium/components/browser_ui/settings/LearnMorePreference.java", "widget/java/src/org/chromium/components/browser_ui/settings/SpinnerPreference.java", "widget/java/src/org/chromium/components/browser_ui/settings/TextMessagePreference.java", @@ -25,6 +26,7 @@ android_library("java") { "//base:base_java", "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/android_deps:androidx_annotation_annotation_java", + "//third_party/android_deps:androidx_appcompat_appcompat_resources_java", "//third_party/android_deps:androidx_preference_preference_java", "//ui/android:ui_java", ] @@ -55,9 +57,11 @@ android_resources("java_resources") { "java/res/layout/preference_spinner.xml", "java/res/layout/preference_spinner_single_line.xml", "java/res/layout/preference_spinner_single_line_item.xml", + "java/res/layout/settings_action_bar_shadow.xml", "java/res/values/attrs.xml", "java/res/values/dimens.xml", "java/res/values/styles.xml", ] + custom_package = "org.chromium.components.browser_ui.settings" } diff --git a/chromium/components/browser_ui/settings/android/java/res/layout/settings_action_bar_shadow.xml b/chromium/components/browser_ui/settings/android/java/res/layout/settings_action_bar_shadow.xml new file mode 100644 index 00000000000..9b326a9178a --- /dev/null +++ b/chromium/components/browser_ui/settings/android/java/res/layout/settings_action_bar_shadow.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2018 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. --> + +<!-- The shadow found below the action bar in settings.--> +<merge + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" > + + <ImageView + android:id="@+id/shadow" + android:layout_width="match_parent" + android:layout_height="@dimen/action_bar_shadow_height" + android:background="@drawable/modern_toolbar_shadow" + android:visibility="gone" + tools:ignore="ContentDescription" /> + +</merge>
\ No newline at end of file diff --git a/chromium/components/browser_ui/settings/android/java/res/values/styles.xml b/chromium/components/browser_ui/settings/android/java/res/values/styles.xml index dd02c6822a8..c0435c8a02a 100644 --- a/chromium/components/browser_ui/settings/android/java/res/values/styles.xml +++ b/chromium/components/browser_ui/settings/android/java/res/values/styles.xml @@ -29,12 +29,6 @@ <item name="android:textAppearance">@style/TextAppearance.TextMedium.Secondary</item> </style> - <!-- TODO(crbug.com/1077375): Consider removing this text style. --> - <style name="TextAppearance.PreferenceMediumText" tools:ignore="UnusedResources"> - <item name="android:textSize">18sp</item> - <item name="android:textColor">?android:attr/textColorPrimary</item> - </style> - <style name="PreferenceLayout"> <item name="android:background">?android:attr/activatedBackgroundIndicator</item> <item name="android:minHeight">?android:attr/listPreferredItemHeightSmall</item> @@ -50,4 +44,41 @@ <item name="android:layout_marginTop">2dp</item> <item name="android:background">@color/modern_grey_600</item> </style> + + <style name="PreferenceTheme"> + <item name="preferenceStyle">@style/PreferenceItem</item> + <item name="preferenceFragmentCompatStyle">@style/SettingsFragment</item> + <item name="preferenceFragmentListStyle">@style/SettingsFragmentList</item> + <item name="dialogPreferenceStyle">@style/DialogPreference</item> + <item name="checkBoxPreferenceStyle">@style/CheckBoxPreference</item> + <item name="switchPreferenceCompatStyle">@style/SwitchPreference</item> + </style> + + <style name="SettingsFragment"> + <item name="android:divider">?android:attr/listDivider</item> + </style> + + <style name="PreferenceItem"> + <item name="android:layout">@layout/preference_compat</item> + </style> + + <style name="SettingsFragmentList"> + <item name="android:paddingStart">0dp</item> + <item name="android:paddingEnd">0dp</item> + </style> + + <style name="DialogPreference"> + <item name="android:layout">@layout/preference_compat</item> + <item name="android:negativeButtonText">@android:string/cancel</item> + </style> + + <style name="CheckBoxPreference"> + <item name="android:layout">@layout/preference_compat</item> + <item name="android:widgetLayout">@layout/preference_widget_checkbox</item> + </style> + + <style name="SwitchPreference"> + <item name="android:layout">@layout/preference_compat</item> + <item name="android:widgetLayout">@layout/preference_widget_switch_compat</item> + </style> </resources> diff --git a/chromium/components/browser_ui/settings/android/widget/java/src/org/chromium/components/browser_ui/settings/ChromeBasePreference.java b/chromium/components/browser_ui/settings/android/widget/java/src/org/chromium/components/browser_ui/settings/ChromeBasePreference.java index 04837e74d81..6c5476db8ad 100644 --- a/chromium/components/browser_ui/settings/android/widget/java/src/org/chromium/components/browser_ui/settings/ChromeBasePreference.java +++ b/chromium/components/browser_ui/settings/android/widget/java/src/org/chromium/components/browser_ui/settings/ChromeBasePreference.java @@ -51,7 +51,6 @@ public class ChromeBasePreference extends Preference { public ChromeBasePreference(Context context, AttributeSet attrs) { super(context, attrs); - setLayoutResource(R.layout.preference_compat); setSingleLineTitle(false); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ChromeBasePreference); diff --git a/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsPreference.java b/chromium/components/browser_ui/settings/android/widget/java/src/org/chromium/components/browser_ui/settings/IconPreference.java index 0e642c7943d..919a222f44c 100644 --- a/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsPreference.java +++ b/chromium/components/browser_ui/settings/android/widget/java/src/org/chromium/components/browser_ui/settings/IconPreference.java @@ -1,8 +1,8 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2020 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.components.browser_ui.site_settings; +package org.chromium.components.browser_ui.settings; import android.content.Context; import android.util.AttributeSet; @@ -11,16 +11,14 @@ import android.widget.ImageView; import androidx.core.view.ViewCompat; import androidx.preference.PreferenceViewHolder; -import org.chromium.components.browser_ui.settings.ChromeBasePreference; - /** - * A custom preference for drawing Site Settings entries. + * A preference with a horizontally centered icon. */ -public class SiteSettingsPreference extends ChromeBasePreference { +public class IconPreference extends ChromeBasePreference { /** * Constructor for inflating from XML. */ - public SiteSettingsPreference(Context context, AttributeSet attrs) { + public IconPreference(Context context, AttributeSet attrs) { super(context, attrs); } @@ -28,6 +26,10 @@ public class SiteSettingsPreference extends ChromeBasePreference { public void onBindViewHolder(PreferenceViewHolder holder) { super.onBindViewHolder(holder); + // Horizontally center the preference icon. + + // TODO(crbug.com/1095981): move this logic to ChromeBasePreference and + // find a way to center it without a hard-coded padding. int padding = getContext().getResources().getDimensionPixelSize(R.dimen.pref_icon_padding); ImageView icon = (ImageView) holder.findViewById(android.R.id.icon); ViewCompat.setPaddingRelative( diff --git a/chromium/components/browser_ui/share/DEPS b/chromium/components/browser_ui/share/DEPS new file mode 100644 index 00000000000..876f1347c5f --- /dev/null +++ b/chromium/components/browser_ui/share/DEPS @@ -0,0 +1,7 @@ +include_rules = [ + "+chrome/android/java/src/org/chromium/chrome/browser/FileProviderHelper.java", + "+components/dom_distiller/core/android", + "+content/public/android", + "+content/public/test/android/javatests", + "+ui/android", +] diff --git a/chromium/components/browser_ui/share/OWNERS b/chromium/components/browser_ui/share/OWNERS new file mode 100644 index 00000000000..109f4d68517 --- /dev/null +++ b/chromium/components/browser_ui/share/OWNERS @@ -0,0 +1,5 @@ +dtrainor@chromium.org + +file://components/send_tab_to_self/OWNERS + +# COMPONENT: UI>Browser>Sharing diff --git a/chromium/components/browser_ui/share/android/BUILD.gn b/chromium/components/browser_ui/share/android/BUILD.gn new file mode 100644 index 00000000000..6c370e7cba3 --- /dev/null +++ b/chromium/components/browser_ui/share/android/BUILD.gn @@ -0,0 +1,53 @@ +# Copyright 2020 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. + +import("//build/config/android/rules.gni") + +android_library("java") { + sources = [ + "java/src/org/chromium/components/browser_ui/share/ShareDialogAdapter.java", + "java/src/org/chromium/components/browser_ui/share/ShareHelper.java", + "java/src/org/chromium/components/browser_ui/share/ShareImageFileUtils.java", + "java/src/org/chromium/components/browser_ui/share/ShareParams.java", + ] + deps = [ + ":java_resources", + "//base:base_java", + "//components/browser_ui/util/android:java", + "//components/dom_distiller/core/android:dom_distiller_core_java", + "//content/public/android:content_java", + "//third_party/android_deps:androidx_annotation_annotation_java", + "//third_party/android_deps:androidx_appcompat_appcompat_java", + "//third_party/android_deps:androidx_core_core_java", + "//ui/android:ui_java", + ] +} + +android_resources("java_resources") { + custom_package = "org.chromium.components.browser_ui.share" + sources = [ "java/res/layout/share_dialog_item.xml" ] + deps = [ + "//components/browser_ui/strings/android:browser_ui_strings_grd", + "//components/browser_ui/styles/android:java_resources", + ] +} + +android_library("javatests") { + testonly = true + + sources = [ "java/src/org/chromium/components/browser_ui/share/ShareImageFileUtilsTest.java" ] + deps = [ + ":java", + "//base:base_java", + "//base:base_java_test_support", + "//chrome/android:chrome_java", + "//content/public/test/android:content_java_test_support", + "//third_party/android_deps:androidx_appcompat_appcompat_java", + "//third_party/android_deps:androidx_core_core_java", + "//third_party/hamcrest:hamcrest_java", + "//third_party/junit", + "//ui/android:ui_java", + "//ui/android:ui_java_test_support", + ] +} diff --git a/chromium/components/browser_ui/share/android/java/res/layout/share_dialog_item.xml b/chromium/components/browser_ui/share/android/java/res/layout/share_dialog_item.xml new file mode 100644 index 00000000000..7a716c41522 --- /dev/null +++ b/chromium/components/browser_ui/share/android/java/res/layout/share_dialog_item.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2014 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. --> + +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="?attr/selectableItemBackground" + android:gravity="center_vertical" + android:orientation="horizontal" > + <ImageView android:id="@+id/icon" + android:layout_width="48dp" + android:layout_height="48dp" + android:layout_marginStart="12dp" + android:padding="4dp" + android:scaleType="fitCenter" + tools:ignore="ContentDescription" /> + <TextView android:id="@+id/text" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="12dp" + android:ellipsize="end" + android:maxLines="2" + android:textAlignment="viewStart" + android:textAppearance="?android:attr/textAppearanceMedium" /> +</LinearLayout>
\ No newline at end of file diff --git a/chromium/components/browser_ui/share/android/java/src/org/chromium/components/browser_ui/share/ShareDialogAdapter.java b/chromium/components/browser_ui/share/android/java/src/org/chromium/components/browser_ui/share/ShareDialogAdapter.java new file mode 100644 index 00000000000..811dfdd3d81 --- /dev/null +++ b/chromium/components/browser_ui/share/android/java/src/org/chromium/components/browser_ui/share/ShareDialogAdapter.java @@ -0,0 +1,52 @@ +// Copyright 2014 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.components.browser_ui.share; + +import android.content.Context; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.ImageView; +import android.widget.TextView; + +import java.util.List; + +/** + * Adapter that provides the list of activities via which a web page can be shared. + */ +class ShareDialogAdapter extends ArrayAdapter<ResolveInfo> { + private final LayoutInflater mInflater; + private final PackageManager mManager; + + /** + * @param context Context used to for layout inflation. + * @param manager PackageManager used to query for activity information. + * @param objects The list of possible share intents. + */ + public ShareDialogAdapter(Context context, PackageManager manager, List<ResolveInfo> objects) { + super(context, R.layout.share_dialog_item, objects); + mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + mManager = manager; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + View view; + if (convertView == null) { + view = mInflater.inflate(R.layout.share_dialog_item, parent, false); + } else { + view = convertView; + } + TextView text = (TextView) view.findViewById(R.id.text); + ImageView icon = (ImageView) view.findViewById(R.id.icon); + + text.setText(getItem(position).loadLabel(mManager)); + icon.setImageDrawable(ShareHelper.loadIconForResolveInfo(getItem(position), mManager)); + return view; + } +} diff --git a/chromium/components/browser_ui/share/android/java/src/org/chromium/components/browser_ui/share/ShareHelper.java b/chromium/components/browser_ui/share/android/java/src/org/chromium/components/browser_ui/share/ShareHelper.java new file mode 100644 index 00000000000..993e5d7c165 --- /dev/null +++ b/chromium/components/browser_ui/share/android/java/src/org/chromium/components/browser_ui/share/ShareHelper.java @@ -0,0 +1,394 @@ +// Copyright 2020 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.components.browser_ui.share; + +import android.annotation.TargetApi; +import android.app.Activity; +import android.app.PendingIntent; +import android.content.BroadcastReceiver; +import android.content.ClipData; +import android.content.ComponentName; +import android.content.Context; +import android.content.DialogInterface; +import android.content.DialogInterface.OnDismissListener; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.ActivityInfo; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.ResolveInfo; +import android.content.res.Resources; +import android.content.res.Resources.NotFoundException; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.os.Build; +import android.text.TextUtils; +import android.view.View; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemClickListener; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; +import androidx.appcompat.app.AlertDialog; + +import org.chromium.base.ApiCompatibilityUtils; +import org.chromium.base.ContextUtils; +import org.chromium.base.PackageManagerUtils; +import org.chromium.components.browser_ui.share.ShareParams.TargetChosenCallback; +import org.chromium.ui.UiUtils; +import org.chromium.ui.base.WindowAndroid; +import org.chromium.ui.base.WindowAndroid.IntentCallback; + +import java.util.Collections; +import java.util.List; + +/** + * A helper class that helps to start an intent to share titles and URLs. + */ +public class ShareHelper { + /** Interface that receives intents for testing (to fake out actually sending them). */ + public interface FakeIntentReceiver { + /** Sets the intent to send back in the broadcast. */ + public void setIntentToSendBack(Intent intent); + + /** Called when a custom chooser dialog is shown. */ + public void onCustomChooserShown(AlertDialog dialog); + + /** + * Simulates firing the given intent, without actually doing so. + * + * @param context The context that will receive broadcasts from the simulated activity. + * @param intent The intent to send to the system. + */ + public void fireIntent(Context context, Intent intent); + } + + /** The task ID of the activity that triggered the share action. */ + public static final String EXTRA_TASK_ID = "org.chromium.chrome.extra.TASK_ID"; + + private static final String EXTRA_SHARE_SCREENSHOT_AS_STREAM = "share_screenshot_as_stream"; + + /** Force the use of a Chrome-specific intent chooser, not the system chooser. */ + private static boolean sForceCustomChooserForTesting; + + /** If non-null, will be used instead of the real activity. */ + private static FakeIntentReceiver sFakeIntentReceiverForTesting; + + protected ShareHelper() {} + + /** + * Fire the intent to share content with the target app. + * + * @param window The current window. + * @param intent The intent to fire. + * @param callback The callback to be triggered when the calling activity has finished. This + * allows the target app to identify Chrome as the source. + */ + protected static void fireIntent( + WindowAndroid window, Intent intent, @Nullable IntentCallback callback) { + if (sFakeIntentReceiverForTesting != null) { + sFakeIntentReceiverForTesting.fireIntent(ContextUtils.getApplicationContext(), intent); + } else if (callback != null) { + window.showIntent(intent, callback, null); + } else { + // TODO(tedchoc): Allow startActivity w/o intent via Window. + Activity activity = window.getActivity().get(); + activity.startActivity(intent); + } + } + + /** + * Force the use of a Chrome-specific intent chooser, not the system chooser. + * + * This emulates the behavior on pre Lollipop-MR1 systems, where the system chooser is not + * available. + */ + public static void setForceCustomChooserForTesting(boolean enabled) { + sForceCustomChooserForTesting = enabled; + } + + /** + * Uses a FakeIntentReceiver instead of actually sending intents to the system. + * + * @param receiver The object to send intents to. If null, resets back to the default behavior + * (really send intents). + */ + public static void setFakeIntentReceiverForTesting(FakeIntentReceiver receiver) { + sFakeIntentReceiverForTesting = receiver; + } + + /** + * Receiver to record the chosen component when sharing an Intent. + */ + public static class TargetChosenReceiver extends BroadcastReceiver implements IntentCallback { + private static final String EXTRA_RECEIVER_TOKEN = "receiver_token"; + private static final Object LOCK = new Object(); + + private static String sTargetChosenReceiveAction; + private static TargetChosenReceiver sLastRegisteredReceiver; + + @Nullable + private TargetChosenCallback mCallback; + + private TargetChosenReceiver(@Nullable TargetChosenCallback callback) { + mCallback = callback; + } + + public static boolean isSupported() { + return !sForceCustomChooserForTesting + && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1; + } + + @TargetApi(Build.VERSION_CODES.LOLLIPOP_MR1) + public static void sendChooserIntent(WindowAndroid window, Intent sharingIntent, + @Nullable TargetChosenCallback callback) { + final Context context = ContextUtils.getApplicationContext(); + final String packageName = context.getPackageName(); + synchronized (LOCK) { + if (sTargetChosenReceiveAction == null) { + sTargetChosenReceiveAction = + packageName + "/" + TargetChosenReceiver.class.getName() + "_ACTION"; + } + if (sLastRegisteredReceiver != null) { + context.unregisterReceiver(sLastRegisteredReceiver); + // Must cancel the callback (to satisfy guarantee that exactly one method of + // TargetChosenCallback is called). + sLastRegisteredReceiver.cancel(); + } + sLastRegisteredReceiver = new TargetChosenReceiver(callback); + context.registerReceiver( + sLastRegisteredReceiver, new IntentFilter(sTargetChosenReceiveAction)); + } + + Intent intent = new Intent(sTargetChosenReceiveAction); + intent.setPackage(packageName); + intent.putExtra(EXTRA_RECEIVER_TOKEN, sLastRegisteredReceiver.hashCode()); + Activity activity = window.getActivity().get(); + final PendingIntent pendingIntent = PendingIntent.getBroadcast(activity, 0, intent, + PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT); + Intent chooserIntent = Intent.createChooser(sharingIntent, + context.getString(R.string.share_link_chooser_title), + pendingIntent.getIntentSender()); + if (sFakeIntentReceiverForTesting != null) { + sFakeIntentReceiverForTesting.setIntentToSendBack(intent); + } + fireIntent(window, chooserIntent, sLastRegisteredReceiver); + } + + @Override + public void onReceive(Context context, Intent intent) { + synchronized (LOCK) { + if (sLastRegisteredReceiver != this) return; + ContextUtils.getApplicationContext().unregisterReceiver(sLastRegisteredReceiver); + sLastRegisteredReceiver = null; + } + if (!intent.hasExtra(EXTRA_RECEIVER_TOKEN) + || intent.getIntExtra(EXTRA_RECEIVER_TOKEN, 0) != this.hashCode()) { + return; + } + + ComponentName target = intent.getParcelableExtra(Intent.EXTRA_CHOSEN_COMPONENT); + if (mCallback != null) { + mCallback.onTargetChosen(target); + mCallback = null; + } + } + + @Override + public void onIntentCompleted(WindowAndroid window, int resultCode, Intent data) { + if (resultCode == Activity.RESULT_CANCELED) { + cancel(); + } + } + + private void cancel() { + if (mCallback != null) { + mCallback.onCancel(); + mCallback = null; + } + } + } + + /** + * Creates and shows a custom share intent picker dialog. + * + * @param params The container holding the share parameters. + */ + static void showCompatShareDialog(final ShareParams params) { + Intent intent = getShareLinkAppCompatibilityIntent(); + List<ResolveInfo> resolveInfoList = PackageManagerUtils.queryIntentActivities(intent, 0); + assert resolveInfoList.size() > 0; + if (resolveInfoList.size() == 0) return; + + final Context context = params.getWindow().getContext().get(); + final PackageManager manager = context.getPackageManager(); + Collections.sort(resolveInfoList, new ResolveInfo.DisplayNameComparator(manager)); + + final ShareDialogAdapter adapter = + new ShareDialogAdapter(context, manager, resolveInfoList); + AlertDialog.Builder builder = new UiUtils.CompatibleAlertDialogBuilder( + context, R.style.Theme_Chromium_AlertDialog); + builder.setTitle(context.getString(R.string.share_link_chooser_title)); + builder.setAdapter(adapter, null); + + final TargetChosenCallback callback = params.getCallback(); + // Need a mutable object to record whether the callback has been fired. + final boolean[] callbackCalled = new boolean[1]; + + final AlertDialog dialog = builder.create(); + dialog.show(); + dialog.getListView().setOnItemClickListener(new OnItemClickListener() { + @Override + public void onItemClick(AdapterView<?> parent, View view, int position, long id) { + ResolveInfo info = adapter.getItem(position); + ActivityInfo ai = info.activityInfo; + ComponentName component = + new ComponentName(ai.applicationInfo.packageName, ai.name); + + if (callback != null && !callbackCalled[0]) { + callback.onTargetChosen(component); + callbackCalled[0] = true; + } + shareDirectly(params, component); + dialog.dismiss(); + } + }); + + dialog.setOnDismissListener(new OnDismissListener() { + @Override + public void onDismiss(DialogInterface dialog) { + if (callback != null && !callbackCalled[0]) { + callback.onCancel(); + callbackCalled[0] = true; + } + } + }); + + if (sFakeIntentReceiverForTesting != null) { + sFakeIntentReceiverForTesting.onCustomChooserShown(dialog); + } + } + + /** + * Shares the params using the system share sheet, or skipping the sheet and sharing directl if + * the target component is specified. + */ + static void shareWithSystemSheet(ShareParams params) { + assert TargetChosenReceiver.isSupported(); + TargetChosenReceiver.sendChooserIntent( + params.getWindow(), getShareLinkIntent(params), params.getCallback()); + } + + /** + * Shows a picker and allows the user to choose a share target. + * + * @param params The container holding the share parameters. + */ + public static void shareWithUi(ShareParams params) { + if (TargetChosenReceiver.isSupported()) { + // On L+ open system share sheet. + shareWithSystemSheet(params); + } else { + // On K and below open custom share dialog. + showCompatShareDialog(params); + } + } + + /** + * Share directly with the provied share target. + * @param params The container holding the share parameters. + * @param component The component to share to, bypassing any UI. + */ + public static void shareDirectly( + @NonNull ShareParams params, @NonNull ComponentName component) { + Intent intent = getShareLinkIntent(params); + intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT | Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP); + intent.setComponent(component); + fireIntent(params.getWindow(), intent, null); + } + + @VisibleForTesting + public static Intent getShareLinkIntent(ShareParams params) { + final boolean isFileShare = (params.getFileUris() != null); + final boolean isMultipleFileShare = isFileShare && (params.getFileUris().size() > 1); + final String action = + isMultipleFileShare ? Intent.ACTION_SEND_MULTIPLE : Intent.ACTION_SEND; + Intent intent = new Intent(action); + intent.addFlags(ApiCompatibilityUtils.getActivityNewDocumentFlag() + | Intent.FLAG_ACTIVITY_FORWARD_RESULT | Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP); + intent.putExtra(EXTRA_TASK_ID, params.getWindow().getActivity().get().getTaskId()); + + Uri screenshotUri = params.getScreenshotUri(); + if (screenshotUri != null) { + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + // To give read access to an Intent target, we need to put |screenshotUri| in clipData + // because adding Intent.FLAG_GRANT_READ_URI_PERMISSION doesn't work for + // EXTRA_SHARE_SCREENSHOT_AS_STREAM. + intent.setClipData(ClipData.newRawUri("", screenshotUri)); + intent.putExtra(EXTRA_SHARE_SCREENSHOT_AS_STREAM, screenshotUri); + } + + if (params.getOfflineUri() != null) { + intent.putExtra(Intent.EXTRA_SUBJECT, params.getTitle()); + intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK); + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + intent.putExtra(Intent.EXTRA_STREAM, params.getOfflineUri()); + intent.addCategory(Intent.CATEGORY_DEFAULT); + intent.setType("multipart/related"); + } else { + if (!TextUtils.equals(params.getText(), params.getTitle())) { + intent.putExtra(Intent.EXTRA_SUBJECT, params.getTitle()); + } + intent.putExtra(Intent.EXTRA_TEXT, params.getText()); + + if (isFileShare) { + intent.setType(params.getFileContentType()); + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + + if (isMultipleFileShare) { + intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, params.getFileUris()); + } else { + intent.putExtra(Intent.EXTRA_STREAM, params.getFileUris().get(0)); + } + } else { + intent.setType("text/plain"); + } + } + + return intent; + } + + /** + * Convenience method to create an Intent to retrieve all the apps support sharing text. + */ + public static Intent getShareLinkAppCompatibilityIntent() { + Intent intent = new Intent(Intent.ACTION_SEND); + intent.addFlags(ApiCompatibilityUtils.getActivityNewDocumentFlag()); + intent.putExtra(Intent.EXTRA_SUBJECT, ""); + intent.putExtra(Intent.EXTRA_TEXT, ""); + intent.setType("text/plain"); + return intent; + } + + /** + * Loads the icon for the provided ResolveInfo. + * @param info The ResolveInfo to load the icon for. + * @param manager The package manager to use to load the icon. + */ + public static Drawable loadIconForResolveInfo(ResolveInfo info, PackageManager manager) { + try { + final int iconRes = info.getIconResource(); + if (iconRes != 0) { + Resources res = manager.getResourcesForApplication(info.activityInfo.packageName); + Drawable icon = ApiCompatibilityUtils.getDrawable(res, iconRes); + return icon; + } + } catch (NameNotFoundException | NotFoundException e) { + // Could not find the icon. loadIcon call below will return the default app icon. + } + return info.loadIcon(manager); + } +} diff --git a/chromium/components/browser_ui/share/android/java/src/org/chromium/components/browser_ui/share/ShareImageFileUtils.java b/chromium/components/browser_ui/share/android/java/src/org/chromium/components/browser_ui/share/ShareImageFileUtils.java new file mode 100644 index 00000000000..246b0c7a9b3 --- /dev/null +++ b/chromium/components/browser_ui/share/android/java/src/org/chromium/components/browser_ui/share/ShareImageFileUtils.java @@ -0,0 +1,449 @@ +// Copyright 2020 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.components.browser_ui.share; + +import android.annotation.TargetApi; +import android.app.DownloadManager; +import android.content.ContentResolver; +import android.content.ContentValues; +import android.content.Context; +import android.graphics.Bitmap; +import android.net.Uri; +import android.os.Environment; +import android.provider.MediaStore; +import android.text.TextUtils; + +import androidx.annotation.VisibleForTesting; + +import org.chromium.base.ApplicationState; +import org.chromium.base.ApplicationStatus; +import org.chromium.base.BuildInfo; +import org.chromium.base.Callback; +import org.chromium.base.ContentUriUtils; +import org.chromium.base.ContextUtils; +import org.chromium.base.FileUtils; +import org.chromium.base.Log; +import org.chromium.base.StreamUtil; +import org.chromium.base.task.AsyncTask; +import org.chromium.components.browser_ui.util.DownloadUtils; +import org.chromium.content_public.browser.RenderWidgetHostView; +import org.chromium.content_public.browser.WebContents; +import org.chromium.ui.UiUtils; +import org.chromium.ui.base.Clipboard; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Locale; + +/** + * Utility class for file operations for image data. + */ +public class ShareImageFileUtils { + private static final String TAG = "share"; + + /** + * Directory name for shared images. + * + * Named "screenshot" for historical reasons as we only initially shared screenshot images. + * TODO(crbug.com/1055886): consider changing the directory name. + */ + private static final String SHARE_IMAGES_DIRECTORY_NAME = "screenshot"; + private static final String JPEG_EXTENSION = ".jpg"; + private static final String FILE_NUMBER_FORMAT = " (%d)"; + private static final String MIME_TYPE = "image/JPEG"; + + /** + * Check if the file related to |fileUri| is in the |folder|. + * + * @param fileUri The {@link Uri} related to the file to be checked. + * @param folder The folder that may contain the |fileUrl|. + * @return Whether the |fileUri| is in the |folder|. + */ + private static boolean isUriInDirectory(Uri fileUri, File folder) { + if (fileUri == null) return false; + + Uri chromeUriPrefix = ContentUriUtils.getContentUriFromFile(folder); + if (chromeUriPrefix == null) return false; + + return fileUri.toString().startsWith(chromeUriPrefix.toString()); + } + + /** + * Check if the system clipboard contains a Uri that comes from Chrome. If yes, return the file + * name from the Uri, otherwise return null. + * + * @return The file name if system clipboard contains a Uri from Chrome, otherwise return null. + */ + private static String getClipboardCurrentFilepath() throws IOException { + Uri clipboardUri = Clipboard.getInstance().getImageUri(); + if (isUriInDirectory(clipboardUri, getSharedFilesDirectory())) { + return clipboardUri.getPath(); + } + return null; + } + + /** + * Returns the directory where temporary files are stored to be shared with external + * applications. These files are deleted on startup and when there are no longer any active + * Activities. + * + * @return The directory where shared files are stored. + */ + public static File getSharedFilesDirectory() throws IOException { + File imagePath = UiUtils.getDirectoryForImageCapture(ContextUtils.getApplicationContext()); + return new File(imagePath, SHARE_IMAGES_DIRECTORY_NAME); + } + + /** + * Clears all shared image files. + */ + public static void clearSharedImages() { + AsyncTask.SERIAL_EXECUTOR.execute(() -> { + try { + String clipboardFilepath = getClipboardCurrentFilepath(); + FileUtils.recursivelyDeleteFile(getSharedFilesDirectory(), (filepath) -> { + return filepath == null || clipboardFilepath == null + || !filepath.endsWith(clipboardFilepath); + }); + } catch (IOException ie) { + // Ignore exception. + } + }); + } + + /** + * Temporarily saves the given set of image bytes and provides that URI to a callback for + * sharing. + * + * @param context The context used to trigger the share action. + * @param imageData The image data to be shared in |fileExtension| format. + * @param fileExtension File extension which |imageData| encoded to. + * @param callback A provided callback function which will act on the generated URI. + */ + public static void generateTemporaryUriFromData(final Context context, final byte[] imageData, + String fileExtension, Callback<Uri> callback) { + if (imageData.length == 0) { + Log.w(TAG, "Share failed -- Received image contains no data."); + return; + } + OnImageSaveListener listener = new OnImageSaveListener() { + @Override + public void onImageSaved(Uri uri, String displayName) { + callback.onResult(uri); + } + @Override + public void onImageSaveError(String displayName) {} + }; + + String fileName = String.valueOf(System.currentTimeMillis()); + // Path is passed as a function because in some cases getting the path should be run on a + // background thread. + saveImage(fileName, + () + -> { return ""; }, + listener, (fos) -> { writeImageData(fos, imageData); }, true, fileExtension); + } + + /** + * Saves bitmap to external storage directory. + * + * @param context The Context to use for determining download location. + * @param filename The filename without extension. + * @param bitmap The Bitmap to download. + * @param listener The OnImageSaveListener to notify the download results. + */ + public static void saveBitmapToExternalStorage( + final Context context, String fileName, Bitmap bitmap, OnImageSaveListener listener) { + // Passing the path as a function so that it can be called on a background thread in + // |saveImage|. + saveImage(fileName, + () + -> { + return context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).getPath(); + }, + listener, (fos) -> { writeBitmap(fos, bitmap); }, false, JPEG_EXTENSION); + } + + /** + * Interface for notifying image download result. + */ + public interface OnImageSaveListener { + void onImageSaved(Uri uri, String displayName); + void onImageSaveError(String displayName); + } + + /** + * Interface for writing image information to a output stream. + */ + private interface FileOutputStreamWriter { + void write(FileOutputStream fos) throws IOException; + } + + /** + * Interface for providing file path. This is used for passing a function for getting the path + * to other function to be called while on a background thread. Should be used on a background + * thread. + */ + private interface FilePathProvider { + String getPath(); + } + + /** + * Saves image to the given file. + * + * @param fileName The File instance of a destination file. + * @param filePathProvider The FilePathProvider for obtaining destination file path. + * @param listener The OnImageSaveListener to notify the download results. + * @param writer The FileOutputStreamWriter that writes to given stream. + * @param isTemporary Indicates whether image should be save to a temporary file. + * @param fileExtension The file's extension. + */ + private static void saveImage(String fileName, FilePathProvider filePathProvider, + OnImageSaveListener listener, FileOutputStreamWriter writer, boolean isTemporary, + String fileExtension) { + new AsyncTask<Uri>() { + @Override + protected Uri doInBackground() { + FileOutputStream fOut = null; + File destFile = null; + try { + destFile = createFile( + fileName, filePathProvider.getPath(), isTemporary, fileExtension); + if (destFile != null && destFile.exists()) { + fOut = new FileOutputStream(destFile); + writer.write(fOut); + } else { + Log.w(TAG, + "Share failed -- Unable to create or write to destination file."); + } + } catch (IOException ie) { + cancel(true); + } finally { + StreamUtil.closeQuietly(fOut); + } + + Uri uri = null; + if (!isTemporary) { + if (BuildInfo.isAtLeastQ()) { + uri = addToMediaStore(destFile); + } else { + long downloadId = addCompletedDownload(destFile); + DownloadManager manager = + (DownloadManager) ContextUtils.getApplicationContext() + .getSystemService(Context.DOWNLOAD_SERVICE); + return manager.getUriForDownloadedFile(downloadId); + } + } else { + uri = FileUtils.getUriForFile(destFile); + } + return uri; + } + + @Override + protected void onCancelled() { + listener.onImageSaveError(fileName); + } + + @Override + protected void onPostExecute(Uri uri) { + if (uri == null) { + listener.onImageSaveError(fileName); + return; + } + + if (ApplicationStatus.getStateForApplication() + == ApplicationState.HAS_DESTROYED_ACTIVITIES) { + return; + } + + listener.onImageSaved(uri, fileName); + } + }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } + + /** + * Creates file with specified path, name and extension. + * + * @param filePath The file path a destination file. + * @param fileName The file name a destination file. + * @param isTemporary Indicates whether image should be save to a temporary file. + * @param fileExtension The file's extension. + * + * @return The new File object. + */ + private static File createFile(String fileName, String filePath, boolean isTemporary, + String fileExtension) throws IOException { + File path; + if (filePath.isEmpty()) { + path = getSharedFilesDirectory(); + } else { + path = new File(filePath); + } + + File newFile = null; + if (path.exists() || path.mkdir()) { + if (isTemporary) { + newFile = File.createTempFile(fileName, fileExtension, path); + } else { + newFile = getNextAvailableFile(filePath, fileName, fileExtension); + } + } + + return newFile; + } + + /** + * Returns next available file for the given fileName. + * + * @param filePath The file path a destination file. + * @param fileName The file name a destination file. + * @param extension The extension a destination file. + * + * @return The new File object. + */ + @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) + public static File getNextAvailableFile(String filePath, String fileName, String extension) + throws IOException { + File destFile = new File(filePath, fileName + extension); + int num = 0; + while (destFile.exists()) { + destFile = new File(filePath, + fileName + String.format(Locale.getDefault(), FILE_NUMBER_FORMAT, ++num) + + extension); + } + destFile.createNewFile(); + + return destFile; + } + + /** + * Writes given bitmap to into the given fos. + * + * @param fos The FileOutputStream to write to. + * @param bitmap The Bitmap to write. + */ + private static void writeBitmap(FileOutputStream fos, Bitmap bitmap) throws IOException { + bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos); + } + + /** + * Writes given data to into the given fos. + * + * @param fos The FileOutputStream to write to. + * @param byte[] The byte[] to write. + */ + private static void writeImageData(FileOutputStream fos, final byte[] data) throws IOException { + fos.write(data); + } + + /** + * This is a pass through to the {@link AndroidDownloadManager} function of the same name. + * @param file The File corresponding to the download. + * @return the download ID of this item as assigned by the download manager. + */ + public static long addCompletedDownload(File file) { + String title = file.getName(); + String path = file.getPath(); + long length = file.length(); + + return DownloadUtils.addCompletedDownload( + title, title, MIME_TYPE, path, length, null, null); + } + + @TargetApi(29) + public static Uri addToMediaStore(File file) { + assert BuildInfo.isAtLeastQ(); + + final ContentValues contentValues = new ContentValues(); + contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, file.getName()); + contentValues.put(MediaStore.MediaColumns.MIME_TYPE, MIME_TYPE); + contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS); + + ContentResolver database = ContextUtils.getApplicationContext().getContentResolver(); + Uri insertUri = database.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, contentValues); + + InputStream input = null; + OutputStream output = null; + try { + input = new FileInputStream(file); + if (insertUri != null) { + output = database.openOutputStream(insertUri); + } + if (output != null) { + byte[] buffer = new byte[4096]; + int byteCount = 0; + while ((byteCount = input.read(buffer)) != -1) { + output.write(buffer, 0, byteCount); + } + } + file.delete(); + } catch (IOException e) { + } finally { + StreamUtil.closeQuietly(input); + StreamUtil.closeQuietly(output); + } + return insertUri; + } + + /** + * Captures a screenshot for the provided web contents, persists it and notifies the file + * provider that the file is ready to be accessed by the client. + * + * The screenshot is compressed to JPEG before being written to the file. + * + * @param contents The WebContents instance for which to capture a screenshot. + * @param width The desired width of the resulting screenshot, or 0 for "auto." + * @param height The desired height of the resulting screenshot, or 0 for "auto." + * @param callback The callback that will be called once the screenshot is saved. + */ + public static void captureScreenshotForContents( + WebContents contents, int width, int height, Callback<Uri> callback) { + RenderWidgetHostView rwhv = contents.getRenderWidgetHostView(); + if (rwhv == null) { + callback.onResult(null); + return; + } + try { + String path = UiUtils.getDirectoryForImageCapture(ContextUtils.getApplicationContext()) + + File.separator + SHARE_IMAGES_DIRECTORY_NAME; + rwhv.writeContentBitmapToDiskAsync( + width, height, path, new ExternallyVisibleUriCallback(callback)); + } catch (IOException e) { + Log.e(TAG, "Error getting content bitmap: ", e); + callback.onResult(null); + } + } + + private static class ExternallyVisibleUriCallback implements Callback<String> { + private Callback<Uri> mComposedCallback; + ExternallyVisibleUriCallback(Callback<Uri> cb) { + mComposedCallback = cb; + } + + @Override + public void onResult(final String path) { + if (TextUtils.isEmpty(path)) { + mComposedCallback.onResult(null); + return; + } + + new AsyncTask<Uri>() { + @Override + protected Uri doInBackground() { + return ContentUriUtils.getContentUriFromFile(new File(path)); + } + + @Override + protected void onPostExecute(Uri uri) { + mComposedCallback.onResult(uri); + } + }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } + } +} diff --git a/chromium/components/browser_ui/share/android/java/src/org/chromium/components/browser_ui/share/ShareImageFileUtilsTest.java b/chromium/components/browser_ui/share/android/java/src/org/chromium/components/browser_ui/share/ShareImageFileUtilsTest.java new file mode 100644 index 00000000000..087d53556ea --- /dev/null +++ b/chromium/components/browser_ui/share/android/java/src/org/chromium/components/browser_ui/share/ShareImageFileUtilsTest.java @@ -0,0 +1,348 @@ +// Copyright 2020 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.components.browser_ui.share; + +import android.annotation.TargetApi; +import android.app.DownloadManager; +import android.content.ContentResolver; +import android.content.ContentUris; +import android.content.Context; +import android.database.Cursor; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.net.Uri; +import android.os.Environment; +import android.os.Looper; +import android.provider.MediaStore; + +import androidx.test.filters.SmallTest; + +import org.hamcrest.Matchers; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.chromium.base.BuildInfo; +import org.chromium.base.Callback; +import org.chromium.base.ContentUriUtils; +import org.chromium.base.ContextUtils; +import org.chromium.base.task.AsyncTask; +import org.chromium.base.test.BaseJUnit4ClassRunner; +import org.chromium.base.test.util.CallbackHelper; +import org.chromium.base.test.util.DisableIf; +import org.chromium.base.test.util.DisabledTest; +import org.chromium.chrome.browser.FileProviderHelper; +import org.chromium.content_public.browser.test.util.Criteria; +import org.chromium.content_public.browser.test.util.CriteriaHelper; +import org.chromium.ui.base.Clipboard; +import org.chromium.ui.test.util.DummyUiActivityTestCase; + +import java.io.File; +import java.io.IOException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +/** + * Tests of {@link ShareImageFileUtils}. + */ +@RunWith(BaseJUnit4ClassRunner.class) +public class ShareImageFileUtilsTest extends DummyUiActivityTestCase { + private static final long WAIT_TIMEOUT_SECONDS = 30L; + private static final byte[] TEST_IMAGE_DATA = new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + private static final String TEST_IMAGE_FILE_NAME = "chrome-test-bitmap"; + private static final String TEST_GIF_IMAGE_FILE_EXTENSION = ".gif"; + private static final String TEST_JPG_IMAGE_FILE_EXTENSION = ".jpg"; + private static final String TEST_PNG_IMAGE_FILE_EXTENSION = ".png"; + + private class GenerateUriCallback extends CallbackHelper implements Callback<Uri> { + private Uri mImageUri; + + public Uri getImageUri() { + return mImageUri; + } + + @Override + public void onResult(Uri uri) { + mImageUri = uri; + notifyCalled(); + } + } + + private class AsyncTaskRunnableHelper extends CallbackHelper implements Runnable { + @Override + public void run() { + notifyCalled(); + } + } + + @Override + public void setUpTest() throws Exception { + super.setUpTest(); + Looper.prepare(); + ContentUriUtils.setFileProviderUtil(new FileProviderHelper()); + } + + @Override + public void tearDownTest() throws Exception { + Clipboard.getInstance().setText(""); + clearSharedImages(); + deleteAllTestImages(); + super.tearDownTest(); + } + + private int fileCount(File file) { + if (file.isFile()) { + return 1; + } + + int count = 0; + if (file.isDirectory()) { + for (File f : file.listFiles()) count += fileCount(f); + } + return count; + } + + private boolean filepathExists(File file, String filepath) { + if (file.isFile() && filepath.endsWith(file.getName())) { + return true; + } + + if (file.isDirectory()) { + for (File f : file.listFiles()) { + if (filepathExists(f, filepath)) return true; + } + } + return false; + } + + private Uri generateAnImageToClipboard(String fileExtension) throws TimeoutException { + GenerateUriCallback imageCallback = new GenerateUriCallback(); + ShareImageFileUtils.generateTemporaryUriFromData( + getActivity(), TEST_IMAGE_DATA, fileExtension, imageCallback); + imageCallback.waitForCallback(0, 1, WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS); + Clipboard.getInstance().setImageUri(imageCallback.getImageUri()); + CriteriaHelper.pollInstrumentationThread(() -> { + Criteria.checkThat(Clipboard.getInstance().getImageUri(), + Matchers.is(imageCallback.getImageUri())); + }); + return imageCallback.getImageUri(); + } + + private Uri generateAnImageToClipboard() throws TimeoutException { + return generateAnImageToClipboard(TEST_JPG_IMAGE_FILE_EXTENSION); + } + + private void clearSharedImages() throws TimeoutException { + ShareImageFileUtils.clearSharedImages(); + + // ShareImageFileUtils::clearSharedImages uses AsyncTask.SERIAL_EXECUTOR to schedule a + // clearing the shared folder job, so schedule a new job and wait for the new job finished + // to make sure ShareImageFileUtils::clearSharedImages's clearing folder job finished. + waitForAsync(); + } + + private void waitForAsync() throws TimeoutException { + AsyncTaskRunnableHelper runnableHelper = new AsyncTaskRunnableHelper(); + AsyncTask.SERIAL_EXECUTOR.execute(runnableHelper); + runnableHelper.waitForCallback(0, 1, WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS); + + AsyncTask.THREAD_POOL_EXECUTOR.execute(runnableHelper); + runnableHelper.waitForCallback(0, 1, WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS); + } + + private void deleteAllTestImages() throws TimeoutException { + AsyncTask.SERIAL_EXECUTOR.execute(() -> { + if (BuildInfo.isAtLeastQ()) { + deleteMediaStoreFiles(); + } + deleteExternalStorageFiles(); + }); + waitForAsync(); + } + + @TargetApi(29) + private void deleteMediaStoreFiles() { + ContentResolver contentResolver = ContextUtils.getApplicationContext().getContentResolver(); + Cursor cursor = + contentResolver.query(MediaStore.Downloads.EXTERNAL_CONTENT_URI, null, null, null); + while (cursor.moveToNext()) { + long id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Downloads._ID)); + Uri uri = ContentUris.withAppendedId(MediaStore.Downloads.EXTERNAL_CONTENT_URI, id); + contentResolver.delete(uri, null, null); + } + } + + public void deleteExternalStorageFiles() { + File externalStorageDir = ContextUtils.getApplicationContext().getExternalFilesDir( + Environment.DIRECTORY_DOWNLOADS); + String[] children = externalStorageDir.list(); + for (int i = 0; i < children.length; i++) { + new File(externalStorageDir, children[i]).delete(); + } + } + + private int fileCountInShareDirectory() throws IOException { + return fileCount(ShareImageFileUtils.getSharedFilesDirectory()); + } + + private boolean fileExistsInShareDirectory(Uri fileUri) throws IOException { + return filepathExists(ShareImageFileUtils.getSharedFilesDirectory(), fileUri.getPath()); + } + + private Bitmap getTestBitmap() { + int size = 10; + Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); + + Canvas canvas = new Canvas(bitmap); + Paint paint = new Paint(); + paint.setColor(android.graphics.Color.GREEN); + canvas.drawRect(0F, 0F, (float) size, (float) size, paint); + return bitmap; + } + + @Test + @SmallTest + public void clipboardUriDoNotClearTest() throws TimeoutException, IOException { + Uri clipboardUri = generateAnImageToClipboard(TEST_GIF_IMAGE_FILE_EXTENSION); + Assert.assertTrue(clipboardUri.getPath().endsWith(TEST_GIF_IMAGE_FILE_EXTENSION)); + clipboardUri = generateAnImageToClipboard(TEST_JPG_IMAGE_FILE_EXTENSION); + Assert.assertTrue(clipboardUri.getPath().endsWith(TEST_JPG_IMAGE_FILE_EXTENSION)); + clipboardUri = generateAnImageToClipboard(TEST_PNG_IMAGE_FILE_EXTENSION); + Assert.assertTrue(clipboardUri.getPath().endsWith(TEST_PNG_IMAGE_FILE_EXTENSION)); + Assert.assertEquals(3, fileCountInShareDirectory()); + + clearSharedImages(); + Assert.assertEquals(1, fileCountInShareDirectory()); + Assert.assertTrue(fileExistsInShareDirectory(clipboardUri)); + } + + @Test + @SmallTest + public void clearEverythingIfNoClipboardImageTest() throws TimeoutException, IOException { + generateAnImageToClipboard(); + generateAnImageToClipboard(); + generateAnImageToClipboard(); + Assert.assertEquals(3, fileCountInShareDirectory()); + + Clipboard.getInstance().setText(""); + clearSharedImages(); + Assert.assertEquals(0, fileCountInShareDirectory()); + } + + @Test + @SmallTest + @DisabledTest(message = "crbug.com/1056059") + public void testSaveBitmap() throws IOException, TimeoutException { + String fileName = TEST_IMAGE_FILE_NAME + "_save_bitmap"; + ShareImageFileUtils.OnImageSaveListener listener = + new ShareImageFileUtils.OnImageSaveListener() { + @Override + public void onImageSaved(Uri uri, String displayName) { + Assert.assertNotNull(uri); + Assert.assertEquals(fileName, displayName); + AsyncTask.SERIAL_EXECUTOR.execute(() -> { + File file = new File(uri.getPath()); + Assert.assertTrue(file.exists()); + Assert.assertTrue(file.isFile()); + }); + + // Wait for the above checks to complete. + try { + waitForAsync(); + } catch (TimeoutException ex) { + } + } + + @Override + public void onImageSaveError(String displayName) { + Assert.fail(); + } + }; + ShareImageFileUtils.saveBitmapToExternalStorage( + getActivity(), fileName, getTestBitmap(), listener); + waitForAsync(); + } + + @Test + @SmallTest + @DisableIf.Build(sdk_is_less_than = 29) + public void testSaveBitmapAndMediaStore() throws IOException, TimeoutException { + String fileName = TEST_IMAGE_FILE_NAME + "_mediastore"; + ShareImageFileUtils.OnImageSaveListener listener = + new ShareImageFileUtils.OnImageSaveListener() { + @Override + public void onImageSaved(Uri uri, String displayName) { + Assert.assertNotNull(uri); + Assert.assertEquals(fileName, displayName); + AsyncTask.SERIAL_EXECUTOR.execute(() -> { + Cursor cursor = getActivity().getContentResolver().query( + uri, null, null, null, null); + Assert.assertNotNull(cursor); + Assert.assertTrue(cursor.moveToFirst()); + Assert.assertEquals(fileName + TEST_JPG_IMAGE_FILE_EXTENSION, + cursor.getString(cursor.getColumnIndex( + MediaStore.MediaColumns.DISPLAY_NAME))); + }); + + // Wait for the above checks to complete. + try { + waitForAsync(); + } catch (TimeoutException ex) { + } + } + + @Override + public void onImageSaveError(String displayName) { + Assert.fail(); + } + }; + ShareImageFileUtils.saveBitmapToExternalStorage( + getActivity(), fileName, getTestBitmap(), listener); + waitForAsync(); + } + + @Test + @SmallTest + public void testGetNextAvailableFile() throws IOException { + String fileName = TEST_IMAGE_FILE_NAME + "_next_availble"; + File externalStorageDir = + getActivity().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS); + File imageFile = ShareImageFileUtils.getNextAvailableFile( + externalStorageDir.getPath(), fileName, TEST_JPG_IMAGE_FILE_EXTENSION); + Assert.assertTrue(imageFile.exists()); + + File imageFile2 = ShareImageFileUtils.getNextAvailableFile( + externalStorageDir.getPath(), fileName, TEST_JPG_IMAGE_FILE_EXTENSION); + Assert.assertTrue(imageFile2.exists()); + Assert.assertNotEquals(imageFile.getPath(), imageFile2.getPath()); + } + + @Test + @SmallTest + @DisableIf.Build(sdk_is_greater_than = 28) + public void testAddCompletedDownload() throws IOException { + String filename = + TEST_IMAGE_FILE_NAME + "_add_completed_download" + TEST_JPG_IMAGE_FILE_EXTENSION; + File externalStorageDir = + getActivity().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS); + File qrcodeFile = new File(externalStorageDir, filename); + Assert.assertTrue(qrcodeFile.createNewFile()); + + long downloadId = ShareImageFileUtils.addCompletedDownload(qrcodeFile); + Assert.assertNotEquals(0L, downloadId); + + DownloadManager downloadManager = + (DownloadManager) getActivity().getSystemService(Context.DOWNLOAD_SERVICE); + DownloadManager.Query query = new DownloadManager.Query().setFilterById(downloadId); + Cursor c = downloadManager.query(query); + + Assert.assertNotNull(c); + Assert.assertTrue(c.moveToFirst()); + Assert.assertEquals( + filename, c.getString(c.getColumnIndexOrThrow(DownloadManager.COLUMN_TITLE))); + c.close(); + } +} diff --git a/chromium/components/browser_ui/share/android/java/src/org/chromium/components/browser_ui/share/ShareParams.java b/chromium/components/browser_ui/share/android/java/src/org/chromium/components/browser_ui/share/ShareParams.java new file mode 100644 index 00000000000..f26655eb4a8 --- /dev/null +++ b/chromium/components/browser_ui/share/android/java/src/org/chromium/components/browser_ui/share/ShareParams.java @@ -0,0 +1,246 @@ +// Copyright 2017 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.components.browser_ui.share; + +import android.content.ComponentName; +import android.net.Uri; +import android.text.TextUtils; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import org.chromium.components.dom_distiller.core.DomDistillerUrlUtils; +import org.chromium.ui.base.WindowAndroid; + +import java.util.ArrayList; + +/** + * A container object for passing share parameters to {@link ShareHelper}. + */ +public class ShareParams { + /** The window that triggered the share action. */ + private final WindowAndroid mWindow; + + /** The title of the page to be shared. */ + private final String mTitle; + + /** + * The text to be shared. If both |text| and |url| are supplied, they are concatenated with a + * space. + */ + private final String mText; + + /** The URL of the page to be shared. */ + private final String mUrl; + + /** The common MIME type of the files to be shared. A wildcard if they have differing types. */ + private final String mFileContentType; + + /** The list of Uris of the files to be shared. */ + private final ArrayList<Uri> mFileUris; + + /** The Uri to the offline MHTML file to be shared. */ + private final Uri mOfflineUri; + + /** The Uri of the screenshot of the page to be shared. */ + private final Uri mScreenshotUri; + + /** + * Optional callback to be called when user makes a choice. Will not be called if receiving a + * response when the user makes a choice is not supported (on older Android versions). + */ + private TargetChosenCallback mCallback; + + private ShareParams(WindowAndroid window, String title, String text, String url, + @Nullable String fileContentType, @Nullable ArrayList<Uri> fileUris, + @Nullable Uri offlineUri, @Nullable Uri screenshotUri, + @Nullable TargetChosenCallback callback) { + mWindow = window; + mTitle = title; + mText = text; + mUrl = url; + mFileContentType = fileContentType; + mFileUris = fileUris; + mOfflineUri = offlineUri; + mScreenshotUri = screenshotUri; + mCallback = callback; + } + + /** + * @return The window that triggered share. + */ + public WindowAndroid getWindow() { + return mWindow; + } + + /** + * @return The title of the page to be shared. + */ + public String getTitle() { + return mTitle; + } + + /** + * @return The text to be shared. + */ + public String getText() { + return mText; + } + + /** + * @return The URL of the page to be shared. + */ + public String getUrl() { + return mUrl; + } + + /** + * @return The MIME type to the arbitrary files to be shared. + */ + @Nullable + public String getFileContentType() { + return mFileContentType; + } + + /** + * @return The Uri to the arbitrary files to be shared. + */ + @Nullable + public ArrayList<Uri> getFileUris() { + return mFileUris; + } + + /** + * @return The Uri to the offline MHTML file to be shared. + */ + @Nullable + public Uri getOfflineUri() { + return mOfflineUri; + } + + /** + * @return The Uri of the screenshot of the page to be shared. + */ + @Nullable + public Uri getScreenshotUri() { + return mScreenshotUri; + } + + /** + * @return The callback to be called when user makes a choice. + */ + @Nullable + public TargetChosenCallback getCallback() { + return mCallback; + } + + /** + * @param callback To be called when user makes a choice. + */ + public void setCallback(@Nullable TargetChosenCallback callback) { + mCallback = callback; + } + + /** The builder for {@link ShareParams} objects. */ + public static class Builder { + private WindowAndroid mWindow; + private String mTitle; + private String mText; + private String mUrl; + private String mFileContentType; + private ArrayList<Uri> mFileUris; + private Uri mOfflineUri; + private Uri mScreenshotUri; + private TargetChosenCallback mCallback; + + public Builder(@NonNull WindowAndroid window, @NonNull String title, @NonNull String url) { + mWindow = window; + mUrl = url; + mTitle = title; + } + + /** + * Sets the text to be shared. + */ + public Builder setText(@NonNull String text) { + mText = text; + return this; + } + + /** + * Sets the MIME type of the arbitrary files to be shared. + */ + public Builder setFileContentType(@NonNull String fileContentType) { + mFileContentType = fileContentType; + return this; + } + + /** + * Sets the Uri of the arbitrary files to be shared. + */ + public Builder setFileUris(@Nullable ArrayList<Uri> fileUris) { + mFileUris = fileUris; + return this; + } + + /** + * Sets the Uri of the offline MHTML file to be shared. + */ + public Builder setOfflineUri(@Nullable Uri offlineUri) { + mOfflineUri = offlineUri; + return this; + } + + /** + * Sets the Uri of the screenshot of the page to be shared. + */ + public Builder setScreenshotUri(@Nullable Uri screenshotUri) { + mScreenshotUri = screenshotUri; + return this; + } + + /** + * Sets the callback to be called when user makes a choice. + */ + public Builder setCallback(@Nullable TargetChosenCallback callback) { + mCallback = callback; + return this; + } + + /** @return A fully constructed {@link ShareParams} object. */ + public ShareParams build() { + if (!TextUtils.isEmpty(mUrl)) { + mUrl = DomDistillerUrlUtils.getOriginalUrlFromDistillerUrl(mUrl); + if (!TextUtils.isEmpty(mText)) { + // Concatenate text and URL with a space. + mText = mText + " " + mUrl; + } else { + mText = mUrl; + } + } + return new ShareParams(mWindow, mTitle, mText, mUrl, mFileContentType, mFileUris, + mOfflineUri, mScreenshotUri, mCallback); + } + } + + /** + * Callback interface for when a target is chosen. + */ + public static interface TargetChosenCallback { + /** + * Called when the user chooses a target in the share dialog. + * + * Note that if the user cancels the share dialog, this callback is never called. + */ + public void onTargetChosen(ComponentName chosenComponent); + + /** + * Called when the user cancels the share dialog. + * + * Guaranteed that either this, or onTargetChosen (but not both) will be called, eventually. + */ + public void onCancel(); + } +} diff --git a/chromium/components/browser_ui/site_settings/DEPS b/chromium/components/browser_ui/site_settings/DEPS index 29ca6c45af1..62df9f80480 100644 --- a/chromium/components/browser_ui/site_settings/DEPS +++ b/chromium/components/browser_ui/site_settings/DEPS @@ -7,6 +7,7 @@ include_rules = [ "+components/embedder_support/android", "+components/location/android", "+components/permissions", + "+components/prefs/android", "+components/subresource_filter/android", "+components/url_formatter/android", "+components/user_prefs", diff --git a/chromium/components/browser_ui/site_settings/android/BUILD.gn b/chromium/components/browser_ui/site_settings/android/BUILD.gn index 894e9a34438..64150f04e4c 100644 --- a/chromium/components/browser_ui/site_settings/android/BUILD.gn +++ b/chromium/components/browser_ui/site_settings/android/BUILD.gn @@ -65,7 +65,6 @@ android_library("java") { "java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsFeatureList.java", "java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsHelpClient.java", "java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsPrefClient.java", - "java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsPreference.java", "java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsPreferenceFragment.java", "java/src/org/chromium/components/browser_ui/site_settings/StorageInfo.java", "java/src/org/chromium/components/browser_ui/site_settings/TriStateSiteSettingsPreference.java", @@ -89,8 +88,10 @@ android_library("java") { "//components/embedder_support/android:util_java", "//components/location/android:location_java", "//components/permissions/android:java", + "//components/prefs/android:java", "//components/subresource_filter/android:java", "//components/url_formatter/android:url_formatter_java", + "//components/user_prefs/android:java", "//content/public/android:content_java", "//services/device/public/java:device_feature_list_java", "//third_party/android_deps:android_support_v7_appcompat_java", @@ -98,6 +99,8 @@ android_library("java") { "//ui/android:ui_full_java", "//ui/android:ui_utils_java", ] + srcjar_deps = + [ "//components/content_settings/android:java_pref_names_srcjar" ] } android_library("javatests") { @@ -105,7 +108,9 @@ android_library("javatests") { sources = [ "javatests/src/org/chromium/components/browser_ui/site_settings/WebsiteAddressTest.java" ] deps = [ ":java", + "//base:base_java", "//base:base_java_test_support", + "//third_party/junit", ] } @@ -182,6 +187,7 @@ android_resources("java_resources") { "java/res/drawable-xxxhdpi/settings_usb.png", "java/res/drawable-xxxhdpi/web_asset.png", "java/res/drawable/ic_person_24dp.xml", + "java/res/drawable/settings_bluetooth.xml", "java/res/layout/add_site_dialog.xml", "java/res/layout/clear_data_dialog.xml", "java/res/layout/clear_storage.xml", diff --git a/chromium/components/browser_ui/site_settings/android/java/res/drawable/settings_bluetooth.xml b/chromium/components/browser_ui/site_settings/android/java/res/drawable/settings_bluetooth.xml new file mode 100644 index 00000000000..0fe09abbbc9 --- /dev/null +++ b/chromium/components/browser_ui/site_settings/android/java/res/drawable/settings_bluetooth.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24"> + <path android:pathData="M0 0h24v24H0z"/> + <path android:fillColor="@color/default_icon_color_secondary_dark" android:pathData="M17.71 7.71L12 2h-1v7.59L6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 11 14.41V22h1l5.71-5.71-4.3-4.29 4.3-4.29zM13 5.83l1.88 1.88L13 9.59V5.83zm1.88 10.46L13 18.17v-3.76l1.88 1.88z"/> +</vector> diff --git a/chromium/components/browser_ui/site_settings/android/java/res/xml/site_settings_preferences.xml b/chromium/components/browser_ui/site_settings/android/java/res/xml/site_settings_preferences.xml index 9f20c01689b..b9b237e08e1 100644 --- a/chromium/components/browser_ui/site_settings/android/java/res/xml/site_settings_preferences.xml +++ b/chromium/components/browser_ui/site_settings/android/java/res/xml/site_settings_preferences.xml @@ -7,94 +7,98 @@ <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <!-- All sites --> - <org.chromium.components.browser_ui.site_settings.SiteSettingsPreference + <org.chromium.components.browser_ui.settings.IconPreference android:fragment="org.chromium.components.browser_ui.site_settings.SingleCategorySettings" android:key="all_sites" android:title="@string/all_sites" android:icon="@drawable/settings_all_sites" app:iconTint="@color/default_icon_color" /> <!-- Cookies --> - <org.chromium.components.browser_ui.site_settings.SiteSettingsPreference + <org.chromium.components.browser_ui.settings.IconPreference android:key="cookies" android:fragment="org.chromium.components.browser_ui.site_settings.SingleCategorySettings" /> <!-- Location --> - <org.chromium.components.browser_ui.site_settings.SiteSettingsPreference + <org.chromium.components.browser_ui.settings.IconPreference android:fragment="org.chromium.components.browser_ui.site_settings.SingleCategorySettings" android:key="device_location" /> <!-- Camera --> - <org.chromium.components.browser_ui.site_settings.SiteSettingsPreference + <org.chromium.components.browser_ui.settings.IconPreference android:fragment="org.chromium.components.browser_ui.site_settings.SingleCategorySettings" android:key="camera" /> <!-- Microphone --> - <org.chromium.components.browser_ui.site_settings.SiteSettingsPreference + <org.chromium.components.browser_ui.settings.IconPreference android:fragment="org.chromium.components.browser_ui.site_settings.SingleCategorySettings" android:key="microphone" /> <!-- Sensors --> - <org.chromium.components.browser_ui.site_settings.SiteSettingsPreference + <org.chromium.components.browser_ui.settings.IconPreference android:fragment="org.chromium.components.browser_ui.site_settings.SingleCategorySettings" android:key="sensors" /> <!-- Notifications --> - <org.chromium.components.browser_ui.site_settings.SiteSettingsPreference + <org.chromium.components.browser_ui.settings.IconPreference android:fragment="org.chromium.components.browser_ui.site_settings.SingleCategorySettings" android:key="notifications" /> <!-- JavaScript --> - <org.chromium.components.browser_ui.site_settings.SiteSettingsPreference + <org.chromium.components.browser_ui.settings.IconPreference android:fragment="org.chromium.components.browser_ui.site_settings.SingleCategorySettings" android:key="javascript" /> <!-- Popups --> - <org.chromium.components.browser_ui.site_settings.SiteSettingsPreference + <org.chromium.components.browser_ui.settings.IconPreference android:fragment="org.chromium.components.browser_ui.site_settings.SingleCategorySettings" android:key="popups" /> <!-- Ads --> - <org.chromium.components.browser_ui.site_settings.SiteSettingsPreference + <org.chromium.components.browser_ui.settings.IconPreference android:fragment="org.chromium.components.browser_ui.site_settings.SingleCategorySettings" android:key="ads" /> <!-- Background sync --> - <org.chromium.components.browser_ui.site_settings.SiteSettingsPreference + <org.chromium.components.browser_ui.settings.IconPreference android:fragment="org.chromium.components.browser_ui.site_settings.SingleCategorySettings" android:key="background_sync" /> <!-- Automatic Downloads --> - <org.chromium.components.browser_ui.site_settings.SiteSettingsPreference + <org.chromium.components.browser_ui.settings.IconPreference android:fragment="org.chromium.components.browser_ui.site_settings.SingleCategorySettings" android:key="automatic_downloads" /> <!-- Protected content --> - <org.chromium.components.browser_ui.site_settings.SiteSettingsPreference + <org.chromium.components.browser_ui.settings.IconPreference android:fragment="org.chromium.components.browser_ui.site_settings.SingleCategorySettings" android:key="protected_content" /> <!-- Sound --> - <org.chromium.components.browser_ui.site_settings.SiteSettingsPreference + <org.chromium.components.browser_ui.settings.IconPreference android:fragment="org.chromium.components.browser_ui.site_settings.SingleCategorySettings" android:key="sound" /> <!-- Storage --> <!-- TODO(finnur): Move this over to the new Usage screen, once it exists. --> - <org.chromium.components.browser_ui.site_settings.SiteSettingsPreference + <org.chromium.components.browser_ui.settings.IconPreference android:fragment="org.chromium.components.browser_ui.site_settings.SingleCategorySettings" android:key="use_storage" android:title="@string/website_settings_storage" android:icon="@drawable/settings_storage" app:iconTint="@color/default_icon_color" /> <!-- NFC --> - <org.chromium.components.browser_ui.site_settings.SiteSettingsPreference + <org.chromium.components.browser_ui.settings.IconPreference android:fragment="org.chromium.components.browser_ui.site_settings.SingleCategorySettings" android:key="nfc" /> <!-- USB --> - <org.chromium.components.browser_ui.site_settings.SiteSettingsPreference + <org.chromium.components.browser_ui.settings.IconPreference android:fragment="org.chromium.components.browser_ui.site_settings.SingleCategorySettings" android:key="usb" /> <!-- Clipboard API --> - <org.chromium.components.browser_ui.site_settings.SiteSettingsPreference + <org.chromium.components.browser_ui.settings.IconPreference android:fragment="org.chromium.components.browser_ui.site_settings.SingleCategorySettings" android:key="clipboard" /> + <!-- Bluetooth --> + <org.chromium.components.browser_ui.settings.IconPreference + android:fragment="org.chromium.components.browser_ui.site_settings.SingleCategorySettings" + android:key="bluetooth" /> <!-- Bluetooth Scanning --> - <org.chromium.components.browser_ui.site_settings.SiteSettingsPreference + <org.chromium.components.browser_ui.settings.IconPreference android:fragment="org.chromium.components.browser_ui.site_settings.SingleCategorySettings" android:key="bluetooth_scanning" /> <!-- VR --> - <org.chromium.components.browser_ui.site_settings.SiteSettingsPreference + <org.chromium.components.browser_ui.settings.IconPreference android:fragment="org.chromium.components.browser_ui.site_settings.SingleCategorySettings" android:key="virtual_reality" /> <!-- AR --> - <org.chromium.components.browser_ui.site_settings.SiteSettingsPreference + <org.chromium.components.browser_ui.settings.IconPreference android:fragment="org.chromium.components.browser_ui.site_settings.SingleCategorySettings" android:key="augmented_reality" /> </PreferenceScreen> diff --git a/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/ContentSettingsResources.java b/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/ContentSettingsResources.java index a8471043b22..89b1ee327c6 100644 --- a/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/ContentSettingsResources.java +++ b/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/ContentSettingsResources.java @@ -118,6 +118,16 @@ public class ContentSettingsResources { R.string.background_sync_permission_title, ContentSettingValues.ALLOW, ContentSettingValues.BLOCK, R.string.website_settings_category_allowed_recommended, 0)); + localMap.put(ContentSettingsType.BLUETOOTH_CHOOSER_DATA, + new ResourceItem(R.drawable.settings_bluetooth, 0, 0, ContentSettingValues.ASK, + ContentSettingValues.BLOCK, 0, 0)); + localMap.put(ContentSettingsType.BLUETOOTH_GUARD, + new ResourceItem(R.drawable.settings_bluetooth, + R.string.website_settings_bluetooth, + R.string.website_settings_bluetooth, ContentSettingValues.ASK, + ContentSettingValues.BLOCK, + R.string.website_settings_category_bluetooth_ask, + R.string.website_settings_category_bluetooth_blocked)); localMap.put(ContentSettingsType.BLUETOOTH_SCANNING, new ResourceItem(R.drawable.ic_bluetooth_searching_black_24dp, R.string.website_settings_bluetooth_scanning, diff --git a/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/PermissionInfo.java b/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/PermissionInfo.java index 488c062dc20..8f11649a727 100644 --- a/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/PermissionInfo.java +++ b/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/PermissionInfo.java @@ -20,7 +20,7 @@ import java.lang.annotation.RetentionPolicy; */ public class PermissionInfo implements Serializable { @IntDef({Type.AUGMENTED_REALITY, Type.CAMERA, Type.CLIPBOARD, Type.GEOLOCATION, Type.MICROPHONE, - Type.MIDI, Type.NOTIFICATION, Type.PROTECTED_MEDIA_IDENTIFIER, Type.SENSORS, + Type.MIDI, Type.NFC, Type.NOTIFICATION, Type.PROTECTED_MEDIA_IDENTIFIER, Type.SENSORS, Type.VIRTUAL_REALITY}) @Retention(RetentionPolicy.SOURCE) public @interface Type { @@ -45,15 +45,22 @@ public class PermissionInfo implements Serializable { } private final boolean mIsIncognito; + private final boolean mIsEmbargoed; private final String mEmbedder; private final String mOrigin; private final @Type int mType; public PermissionInfo(@Type int type, String origin, String embedder, boolean isIncognito) { + this(type, origin, embedder, isIncognito, false); + } + + public PermissionInfo(@Type int type, String origin, String embedder, boolean isIncognito, + boolean isEmbargoed) { mOrigin = origin; mEmbedder = embedder; mIsIncognito = isIncognito; mType = type; + mIsEmbargoed = isEmbargoed; } public @Type int getType() { @@ -76,6 +83,10 @@ public class PermissionInfo implements Serializable { return mEmbedder != null ? mEmbedder : mOrigin; } + public boolean isEmbargoed() { + return mIsEmbargoed; + } + /** * Returns the ContentSetting value for this origin. */ @@ -205,4 +216,36 @@ public class PermissionInfo implements Serializable { return ContentSettingsType.DEFAULT; } } + + /** + * If conversion is not possible, method returns null. + */ + public static @Type Integer getPermissionInfoType(@ContentSettingsType int type) { + switch (type) { + case ContentSettingsType.AR: + return Type.AUGMENTED_REALITY; + case ContentSettingsType.MEDIASTREAM_CAMERA: + return Type.CAMERA; + case ContentSettingsType.CLIPBOARD_READ_WRITE: + return Type.CLIPBOARD; + case ContentSettingsType.GEOLOCATION: + return Type.GEOLOCATION; + case ContentSettingsType.MEDIASTREAM_MIC: + return Type.MICROPHONE; + case ContentSettingsType.MIDI_SYSEX: + return Type.MIDI; + case ContentSettingsType.NFC: + return Type.NFC; + case ContentSettingsType.NOTIFICATIONS: + return Type.NOTIFICATION; + case ContentSettingsType.PROTECTED_MEDIA_IDENTIFIER: + return Type.PROTECTED_MEDIA_IDENTIFIER; + case ContentSettingsType.SENSORS: + return Type.SENSORS; + case ContentSettingsType.VR: + return Type.VIRTUAL_REALITY; + default: + return null; + } + } } diff --git a/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleCategorySettings.java b/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleCategorySettings.java index 68503a37405..6ab6038f9c0 100644 --- a/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleCategorySettings.java +++ b/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleCategorySettings.java @@ -6,6 +6,8 @@ package org.chromium.components.browser_ui.site_settings; import static org.chromium.components.browser_ui.settings.SearchUtils.handleSearchNavigation; import static org.chromium.components.browser_ui.site_settings.WebsitePreferenceBridge.SITE_WILDCARD; +import static org.chromium.components.content_settings.PrefNames.BLOCK_THIRD_PARTY_COOKIES; +import static org.chromium.components.content_settings.PrefNames.COOKIE_CONTROLS_MODE; import android.content.Context; import android.content.DialogInterface; @@ -53,6 +55,8 @@ import org.chromium.components.content_settings.ContentSettingsType; import org.chromium.components.content_settings.CookieControlsMode; import org.chromium.components.embedder_support.browser_context.BrowserContextHandle; import org.chromium.components.embedder_support.util.UrlUtilities; +import org.chromium.components.prefs.PrefService; +import org.chromium.components.user_prefs.UserPrefs; import org.chromium.ui.widget.Toast; import java.util.ArrayList; @@ -518,6 +522,7 @@ public class SingleCategorySettings extends SiteSettingsPreferenceFragment public boolean onPreferenceChange(Preference preference, Object newValue) { BrowserContextHandle browserContextHandle = getSiteSettingsClient().getBrowserContextHandle(); + PrefService prefService = UserPrefs.get(browserContextHandle); if (BINARY_TOGGLE_KEY.equals(preference.getKey())) { assert !mCategory.isManaged(); @@ -551,7 +556,7 @@ public class SingleCategorySettings extends SiteSettingsPreferenceFragment setCookieSettingsPreference((CookieSettingsState) newValue); getInfoForOrigins(); } else if (THIRD_PARTY_COOKIES_TOGGLE_KEY.equals(preference.getKey())) { - getPrefs().setBlockThirdPartyCookies((boolean) newValue); + prefService.setBoolean(BLOCK_THIRD_PARTY_COOKIES, (boolean) newValue); } else if (NOTIFICATIONS_VIBRATE_TOGGLE_KEY.equals(preference.getKey())) { getPrefs().setNotificationsVibrateEnabled((boolean) newValue); } else if (NOTIFICATIONS_QUIET_UI_TOGGLE_KEY.equals(preference.getKey())) { @@ -595,8 +600,10 @@ public class SingleCategorySettings extends SiteSettingsPreferenceFragment WebsitePreferenceBridge.setCategoryEnabled( getSiteSettingsClient().getBrowserContextHandle(), ContentSettingsType.COOKIES, allowCookies); - getPrefs().setCookieControlsMode(mode); - getPrefs().setBlockThirdPartyCookies(mode == CookieControlsMode.BLOCK_THIRD_PARTY); + PrefService prefService = UserPrefs.get(getSiteSettingsClient().getBrowserContextHandle()); + prefService.setInteger(COOKIE_CONTROLS_MODE, mode); + prefService.setBoolean( + BLOCK_THIRD_PARTY_COOKIES, mode == CookieControlsMode.BLOCK_THIRD_PARTY); } private boolean cookieSettingsExceptionShouldBlock() { @@ -865,7 +872,7 @@ public class SingleCategorySettings extends SiteSettingsPreferenceFragment for (Website site : sites) { for (ChosenObjectInfo info : site.getChosenObjectInfo()) { if (mSearch == null || mSearch.isEmpty() - || info.getName().toLowerCase().contains(mSearch)) { + || info.getName().toLowerCase(Locale.getDefault()).contains(mSearch)) { Pair<ArrayList<ChosenObjectInfo>, ArrayList<Website>> entry = objects.get(info.getObject()); if (entry == null) { @@ -890,8 +897,8 @@ public class SingleCategorySettings extends SiteSettingsPreferenceFragment extras.putString(EXTRA_TITLE, getActivity().getTitle().toString()); extras.putSerializable(ChosenObjectSettings.EXTRA_OBJECT_INFOS, entry.first); extras.putSerializable(ChosenObjectSettings.EXTRA_SITES, entry.second); - preference.setIcon( - ContentSettingsResources.getIcon(mCategory.getContentSettingsType())); + preference.setIcon(SettingsUtils.getTintedIcon(getActivity(), + ContentSettingsResources.getIcon(mCategory.getContentSettingsType()))); preference.setTitle(entry.first.get(0).getName()); preference.setFragment(ChosenObjectSettings.class.getCanonicalName()); getPreferenceScreen().addPreference(preference); @@ -1016,7 +1023,8 @@ public class SingleCategorySettings extends SiteSettingsPreferenceFragment } // Only show the link that explains protected content settings when needed. - if (mCategory.showSites(SiteSettingsCategory.Type.PROTECTED_MEDIA)) { + if (mCategory.showSites(SiteSettingsCategory.Type.PROTECTED_MEDIA) + && getSiteSettingsClient().getSiteSettingsHelpClient().isHelpAndFeedbackEnabled()) { explainProtectedMediaKey.setOnPreferenceClickListener(preference -> { getSiteSettingsClient() .getSiteSettingsHelpClient() @@ -1075,10 +1083,12 @@ public class SingleCategorySettings extends SiteSettingsPreferenceFragment new FourStateCookieSettingsPreference.Params(); params.allowCookies = WebsitePreferenceBridge.isCategoryEnabled( getSiteSettingsClient().getBrowserContextHandle(), ContentSettingsType.COOKIES); - params.blockThirdPartyCookies = getPrefs().getBlockThirdPartyCookies(); - params.cookieControlsMode = getPrefs().getCookieControlsMode(); + PrefService prefService = UserPrefs.get(getSiteSettingsClient().getBrowserContextHandle()); + params.blockThirdPartyCookies = prefService.getBoolean(BLOCK_THIRD_PARTY_COOKIES); + params.cookieControlsMode = prefService.getInteger(COOKIE_CONTROLS_MODE); params.cookiesContentSettingEnforced = mCategory.isManaged(); - params.thirdPartyBlockingEnforced = getPrefs().isBlockThirdPartyCookiesManaged(); + params.thirdPartyBlockingEnforced = + prefService.isManagedPreference(BLOCK_THIRD_PARTY_COOKIES); fourStateCookieToggle.setState(params); } @@ -1125,14 +1135,15 @@ public class SingleCategorySettings extends SiteSettingsPreferenceFragment ChromeBaseCheckBoxPreference thirdPartyCookiesPref = (ChromeBaseCheckBoxPreference) getPreferenceScreen().findPreference( THIRD_PARTY_COOKIES_TOGGLE_KEY); - thirdPartyCookiesPref.setChecked(getPrefs().getBlockThirdPartyCookies()); + PrefService prefService = UserPrefs.get(getSiteSettingsClient().getBrowserContextHandle()); + thirdPartyCookiesPref.setChecked(prefService.getBoolean(BLOCK_THIRD_PARTY_COOKIES)); thirdPartyCookiesPref.setEnabled(WebsitePreferenceBridge.isCategoryEnabled( getSiteSettingsClient().getBrowserContextHandle(), ContentSettingsType.COOKIES)); thirdPartyCookiesPref.setManagedPreferenceDelegate(new ForwardingManagedPreferenceDelegate( getSiteSettingsClient().getManagedPreferenceDelegate()) { @Override public boolean isPreferenceControlledByPolicy(Preference preference) { - return getPrefs().isBlockThirdPartyCookiesManaged(); + return prefService.isManagedPreference(BLOCK_THIRD_PARTY_COOKIES); } }); } diff --git a/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java b/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java index edcf1a9ebb9..c1a5bb603e6 100644 --- a/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java +++ b/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java @@ -350,7 +350,9 @@ public class SingleWebsiteSettings extends SiteSettingsPreferenceFragment } else if (i == ContentSettingException.Type.JAVASCRIPT) { setUpJavascriptPreference(preference); } else { - setUpListPreference(preference, mSite.getContentSettingPermission(i)); + // ContentSettingException can not be embargoed. + setUpListPreference(preference, mSite.getContentSettingPermission(i), + false /* isEmbargoed */); } return; } @@ -362,17 +364,23 @@ public class SingleWebsiteSettings extends SiteSettingsPreferenceFragment if (i == PermissionInfo.Type.GEOLOCATION) { setUpLocationPreference(preference); } else if (i == PermissionInfo.Type.NOTIFICATION) { - setUpNotificationsPreference(preference); + setUpNotificationsPreference( + preference, isPermissionEmbargoed(PermissionInfo.Type.NOTIFICATION)); } else { setUpListPreference(preference, mSite.getPermission( - getSiteSettingsClient().getBrowserContextHandle(), i)); + getSiteSettingsClient().getBrowserContextHandle(), i), + isPermissionEmbargoed(i)); } return; } } } + private boolean isPermissionEmbargoed(@PermissionInfo.Type int type) { + return mSite.getPermissionInfo(type) != null && mSite.getPermissionInfo(type).isEmbargoed(); + } + private void setUpClearDataPreference(ClearWebsiteStorage preference) { long usage = mSite.getTotalUsage(); if (usage > 0) { @@ -452,7 +460,7 @@ public class SingleWebsiteSettings extends SiteSettingsPreferenceFragment }); } - private void setUpNotificationsPreference(Preference preference) { + private void setUpNotificationsPreference(Preference preference, boolean isEmbargoed) { WebappSettingsClient client = getSiteSettingsClient().getWebappSettingsClient(); Origin origin = Origin.create(mSite.getAddress().getOrigin()); if (origin != null) { @@ -482,14 +490,15 @@ public class SingleWebsiteSettings extends SiteSettingsPreferenceFragment getPreferenceScreen().removePreference(preference); return; } - String overrideSummary; if (isPermissionControlledByDSE(ContentSettingsType.NOTIFICATIONS)) { overrideSummary = getString(value != null && value == ContentSettingValues.ALLOW ? R.string.website_settings_permissions_allow_dse : R.string.website_settings_permissions_block_dse); } else { - overrideSummary = getString(ContentSettingsResources.getSiteSummary(value)); + overrideSummary = isEmbargoed + ? getString(R.string.automatically_blocked) + : getString(ContentSettingsResources.getSiteSummary(value)); } // On Android O this preference is read-only, so we replace the existing pref with a @@ -503,7 +512,7 @@ public class SingleWebsiteSettings extends SiteSettingsPreferenceFragment return true; }); } else { - setUpListPreference(preference, value); + setUpListPreference(preference, value, isEmbargoed); if (isPermissionControlledByDSE(ContentSettingsType.NOTIFICATIONS) && value != null) { updatePreferenceForDSESetting(preference); } @@ -512,14 +521,9 @@ public class SingleWebsiteSettings extends SiteSettingsPreferenceFragment // This is implemented as a public utility function to better facilitate testing. public void launchOsChannelSettingsFromPreference(Preference preference) { - final boolean blockedByEmbargo = - (WebsitePreferenceBridgeJni.get().isNotificationEmbargoedForOrigin( - getSiteSettingsClient().getBrowserContextHandle(), - mSite.getAddress().getOrigin())); - // There is no notification channel if the origin is merely embargoed. Create it // just-in-time if the user tries to change to setting. - if (blockedByEmbargo) { + if (isPermissionEmbargoed(PermissionInfo.Type.NOTIFICATION)) { mSite.setPermission(getSiteSettingsClient().getBrowserContextHandle(), PermissionInfo.Type.NOTIFICATION, ContentSettingValues.BLOCK); } @@ -567,7 +571,7 @@ public class SingleWebsiteSettings extends SiteSettingsPreferenceFragment findPreference(PERMISSION_PREFERENCE_KEYS[PermissionInfo.Type.NOTIFICATION + ContentSettingException.Type.NUM_ENTRIES]); if (notificationsPreference != null) { - setUpNotificationsPreference(notificationsPreference); + setUpNotificationsPreference(notificationsPreference, false /* isEmbargoed */); } // To ensure UMA receives notification revocations, we detect if the setting has changed @@ -608,7 +612,8 @@ public class SingleWebsiteSettings extends SiteSettingsPreferenceFragment new ChromeImageViewPreference(getStyledContext()); preference.setKey(CHOOSER_PERMISSION_PREFERENCE_KEY); - preference.setIcon(ContentSettingsResources.getIcon(info.getContentSettingsType())); + preference.setIcon(SettingsUtils.getTintedIcon(getActivity(), + ContentSettingsResources.getIcon(info.getContentSettingsType()))); preference.setOrder(maxPermissionOrder); preference.setTitle(info.getName()); preference.setImageView(R.drawable.ic_delete_white_24dp, @@ -745,8 +750,8 @@ public class SingleWebsiteSettings extends SiteSettingsPreferenceFragment * @param preference The ListPreference to initialize. * @param value The value to initialize it to. */ - private void setUpListPreference( - Preference preference, @ContentSettingValues @Nullable Integer value) { + private void setUpListPreference(Preference preference, + @ContentSettingValues @Nullable Integer value, boolean isEmbargoed) { if (value == null) { getPreferenceScreen().removePreference(preference); return; @@ -764,12 +769,12 @@ public class SingleWebsiteSettings extends SiteSettingsPreferenceFragment getString(ContentSettingsResources.getSiteSummary(ContentSettingValues.BLOCK)); listPreference.setEntryValues(keys); listPreference.setEntries(descriptions); + listPreference.setOnPreferenceChangeListener(this); + listPreference.setSummary(isEmbargoed ? getString(R.string.automatically_blocked) : "%s"); // TODO(crbug.com/735110): Figure out if this is the correct thing to do - here we are // effectively treating non-ALLOW values as BLOCK. int index = (value == ContentSettingValues.ALLOW ? 0 : 1); listPreference.setValueIndex(index); - listPreference.setOnPreferenceChangeListener(this); - listPreference.setSummary("%s"); } /** @@ -803,7 +808,8 @@ public class SingleWebsiteSettings extends SiteSettingsPreferenceFragment @Nullable Integer permission = mSite.getPermission( getSiteSettingsClient().getBrowserContextHandle(), PermissionInfo.Type.GEOLOCATION); - setUpListPreference(preference, permission); + setUpListPreference( + preference, permission, isPermissionEmbargoed(PermissionInfo.Type.GEOLOCATION)); if (isPermissionControlledByDSE(ContentSettingsType.GEOLOCATION) && permission != null) { updatePreferenceForDSESetting(preference); } @@ -823,7 +829,8 @@ public class SingleWebsiteSettings extends SiteSettingsPreferenceFragment ? ContentSettingValues.ALLOW : ContentSettingValues.BLOCK; } - setUpListPreference(preference, currentValue); + // Not possible to embargo SOUND. + setUpListPreference(preference, currentValue, false /* isEmbargoed */); } private void setUpJavascriptPreference(Preference preference) { @@ -839,7 +846,8 @@ public class SingleWebsiteSettings extends SiteSettingsPreferenceFragment ContentSettingsType.JAVASCRIPT)) { currentValue = ContentSettingValues.BLOCK; } - setUpListPreference(preference, currentValue); + // Not possible to embargo JAVASCRIPT. + setUpListPreference(preference, currentValue, false /* isEmbargoed */); } /** @@ -852,7 +860,7 @@ public class SingleWebsiteSettings extends SiteSettingsPreferenceFragment private void setUpAdsPreference(Preference preference) { // Do not show the setting if the category is not enabled. if (!SiteSettingsCategory.adsCategoryEnabled()) { - setUpListPreference(preference, null); + setUpListPreference(preference, null, false); return; } // If the ad blocker is activated, then this site will have ads blocked unless there is an @@ -867,7 +875,7 @@ public class SingleWebsiteSettings extends SiteSettingsPreferenceFragment // If the site is not considered a candidate for blocking, do the standard thing and remove // the preference. if (permission == null && !activated) { - setUpListPreference(preference, null); + setUpListPreference(preference, null, false); return; } @@ -880,7 +888,8 @@ public class SingleWebsiteSettings extends SiteSettingsPreferenceFragment ? ContentSettingValues.ALLOW : ContentSettingValues.BLOCK; } - setUpListPreference(preference, permission); + // Not possible to embargo ADS. + setUpListPreference(preference, permission, false /* isEmbargoed */); // The subresource filter permission has a custom BLOCK string. ListPreference listPreference = (ListPreference) preference; @@ -935,6 +944,8 @@ public class SingleWebsiteSettings extends SiteSettingsPreferenceFragment public boolean onPreferenceChange(Preference preference, Object newValue) { @ContentSettingValues int permission = ContentSetting.fromString((String) newValue); + // Embargoed permission preserves summary. Refresh it manually. + preference.setSummary("%s"); BrowserContextHandle browserContextHandle = getSiteSettingsClient().getBrowserContextHandle(); for (int i = 0; i < PERMISSION_PREFERENCE_KEYS.length; i++) { diff --git a/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettings.java b/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettings.java index a03499bd5ac..2c75d1125f0 100644 --- a/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettings.java +++ b/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettings.java @@ -4,6 +4,8 @@ package org.chromium.components.browser_ui.site_settings; +import static org.chromium.components.content_settings.PrefNames.BLOCK_THIRD_PARTY_COOKIES; + import android.os.Bundle; import androidx.preference.Preference; @@ -12,6 +14,7 @@ import org.chromium.components.browser_ui.settings.SettingsUtils; import org.chromium.components.browser_ui.site_settings.SiteSettingsCategory.Type; import org.chromium.components.content_settings.ContentSettingValues; import org.chromium.components.embedder_support.browser_context.BrowserContextHandle; +import org.chromium.components.user_prefs.UserPrefs; /** * The main Site Settings screen, which shows all the site settings categories: All sites, Location, @@ -96,9 +99,7 @@ public class SiteSettings // Show 'disabled' message when permission is not granted in Android. p.setSummary(ContentSettingsResources.getCategorySummary(contentType, false)); } else if (Type.COOKIES == prefCategory && checked - && getSiteSettingsClient() - .getSiteSettingsPrefClient() - .getBlockThirdPartyCookies()) { + && UserPrefs.get(browserContextHandle).getBoolean(BLOCK_THIRD_PARTY_COOKIES)) { p.setSummary(ContentSettingsResources.getCookieAllowedExceptThirdPartySummary()); } else if (Type.DEVICE_LOCATION == prefCategory && checked && WebsitePreferenceBridge.isLocationAllowedByPolicy(browserContextHandle)) { diff --git a/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsCategory.java b/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsCategory.java index f38e075c2a1..ae11552e0ed 100644 --- a/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsCategory.java +++ b/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsCategory.java @@ -39,10 +39,10 @@ import java.lang.annotation.RetentionPolicy; */ public class SiteSettingsCategory { @IntDef({Type.ALL_SITES, Type.ADS, Type.AUGMENTED_REALITY, Type.AUTOMATIC_DOWNLOADS, - Type.BACKGROUND_SYNC, Type.BLUETOOTH_SCANNING, Type.CAMERA, Type.CLIPBOARD, - Type.COOKIES, Type.DEVICE_LOCATION, Type.JAVASCRIPT, Type.MICROPHONE, Type.NFC, - Type.NOTIFICATIONS, Type.POPUPS, Type.PROTECTED_MEDIA, Type.SENSORS, Type.SOUND, - Type.USB, Type.VIRTUAL_REALITY, Type.USE_STORAGE}) + Type.BACKGROUND_SYNC, Type.BLUETOOTH, Type.BLUETOOTH_SCANNING, Type.CAMERA, + Type.CLIPBOARD, Type.COOKIES, Type.DEVICE_LOCATION, Type.JAVASCRIPT, Type.MICROPHONE, + Type.NFC, Type.NOTIFICATIONS, Type.POPUPS, Type.PROTECTED_MEDIA, Type.SENSORS, + Type.SOUND, Type.USB, Type.VIRTUAL_REALITY, Type.USE_STORAGE}) @Retention(RetentionPolicy.SOURCE) public @interface Type { // Values used to address array index - should be enumerated from 0 and can't have gaps. @@ -67,12 +67,13 @@ public class SiteSettingsCategory { int SENSORS = 16; int SOUND = 17; int USB = 18; - int VIRTUAL_REALITY = 19; - int USE_STORAGE = 20; // Always last as it should appear in the UI at the bottom. + int BLUETOOTH = 19; + int VIRTUAL_REALITY = 20; + int USE_STORAGE = 21; // Always last as it should appear in the UI at the bottom. /** * Number of handled categories used for calculating array sizes. */ - int NUM_ENTRIES = 21; + int NUM_ENTRIES = 22; } private final BrowserContextHandle mBrowserContextHandle; @@ -156,6 +157,8 @@ public class SiteSettingsCategory { return ContentSettingsType.AUTOMATIC_DOWNLOADS; case Type.BACKGROUND_SYNC: return ContentSettingsType.BACKGROUND_SYNC; + case Type.BLUETOOTH: + return ContentSettingsType.BLUETOOTH_GUARD; case Type.BLUETOOTH_SCANNING: return ContentSettingsType.BLUETOOTH_SCANNING; case Type.CAMERA: @@ -201,6 +204,8 @@ public class SiteSettingsCategory { switch (type) { case ContentSettingsType.USB_GUARD: return ContentSettingsType.USB_CHOOSER_DATA; + case ContentSettingsType.BLUETOOTH_GUARD: + return ContentSettingsType.BLUETOOTH_CHOOSER_DATA; default: return -1; // Conversion unavailable. } @@ -221,6 +226,8 @@ public class SiteSettingsCategory { return "automatic_downloads"; case Type.BACKGROUND_SYNC: return "background_sync"; + case Type.BLUETOOTH: + return "bluetooth"; case Type.BLUETOOTH_SCANNING: return "bluetooth_scanning"; case Type.CAMERA: diff --git a/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsPrefClient.java b/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsPrefClient.java index ab24de08ddb..605da219084 100644 --- a/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsPrefClient.java +++ b/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsPrefClient.java @@ -12,13 +12,6 @@ package org.chromium.components.browser_ui.site_settings; */ // TODO(crbug.com/1071603): Remove this once PrefServiceBridge is componentized. public interface SiteSettingsPrefClient { - boolean getBlockThirdPartyCookies(); - void setBlockThirdPartyCookies(boolean newValue); - boolean isBlockThirdPartyCookiesManaged(); - - int getCookieControlsMode(); - void setCookieControlsMode(int newValue); - boolean getEnableQuietNotificationPermissionUi(); void setEnableQuietNotificationPermissionUi(boolean newValue); void clearEnableNotificationPermissionUi(); diff --git a/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePermissionsFetcher.java b/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePermissionsFetcher.java index f6ba7418ff3..bddd75f7b38 100644 --- a/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePermissionsFetcher.java +++ b/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePermissionsFetcher.java @@ -131,21 +131,37 @@ public class WebsitePermissionsFetcher { queue.add(new PermissionInfoFetcher(PermissionInfo.Type.CLIPBOARD)); // Sensors permission is per-origin. queue.add(new PermissionInfoFetcher(PermissionInfo.Type.SENSORS)); + + // There are two Bluetooth related permissions: Bluetooth scanning and + // Bluetooth guard. + // + // The Bluetooth Scanning permission controls access to the Web Bluetooth + // Scanning API, which enables sites to scan for and receive events for + // advertisement packets received from nearby Bluetooth devices. CommandLine commandLine = CommandLine.getInstance(); if (commandLine.hasSwitch(ContentSwitches.ENABLE_EXPERIMENTAL_WEB_PLATFORM_FEATURES)) { // Bluetooth scanning permission is per-origin. queue.add(new ExceptionInfoFetcher(ContentSettingsType.BLUETOOTH_SCANNING)); } + // The Bluetooth guard permission controls access to the Web Bluetooth + // API, which enables sites to request access to connect to specific + // Bluetooth devices. Users are presented with a chooser prompt in which + // they must select the Bluetooth device that they would like to allow + // the site to connect to. Therefore, this permission also displays a + // list of permitted Bluetooth devices that each site can connect to. + if (ContentFeatureList.isEnabled( + ContentFeatureList.WEB_BLUETOOTH_NEW_PERMISSIONS_BACKEND)) { + // Bluetooth device permission is per-origin and per-embedder. + queue.add(new ChooserExceptionInfoFetcher(ContentSettingsType.BLUETOOTH_GUARD)); + } if (ContentFeatureList.isEnabled(ContentFeatureList.WEB_NFC)) { // NFC permission is per-origin and per-embedder. queue.add(new PermissionInfoFetcher(PermissionInfo.Type.NFC)); } - if (ContentFeatureList.isEnabled(ContentFeatureList.WEBXR_PERMISSIONS_API)) { - // VIRTUAL_REALITY permission is per-origin and per-embedder. - queue.add(new PermissionInfoFetcher(PermissionInfo.Type.VIRTUAL_REALITY)); - // AR permission is per-origin and per-embedder. - queue.add(new PermissionInfoFetcher(PermissionInfo.Type.AUGMENTED_REALITY)); - } + // VIRTUAL_REALITY permission is per-origin and per-embedder. + queue.add(new PermissionInfoFetcher(PermissionInfo.Type.VIRTUAL_REALITY)); + // AR permission is per-origin and per-embedder. + queue.add(new PermissionInfoFetcher(PermissionInfo.Type.AUGMENTED_REALITY)); queue.add(new PermissionsAvailableCallbackRunner(callback)); @@ -215,6 +231,9 @@ public class WebsitePermissionsFetcher { } else if (category.showSites(SiteSettingsCategory.Type.USB)) { // USB device permission is per-origin. queue.add(new ChooserExceptionInfoFetcher(ContentSettingsType.USB_GUARD)); + } else if (category.showSites(SiteSettingsCategory.Type.BLUETOOTH)) { + // Bluetooth device permission is per-origin. + queue.add(new ChooserExceptionInfoFetcher(ContentSettingsType.BLUETOOTH_GUARD)); } else if (category.showSites(SiteSettingsCategory.Type.CLIPBOARD)) { // Clipboard permission is per-origin. queue.add(new PermissionInfoFetcher(PermissionInfo.Type.CLIPBOARD)); @@ -233,15 +252,11 @@ public class WebsitePermissionsFetcher { queue.add(new PermissionInfoFetcher(PermissionInfo.Type.NFC)); } } else if (category.showSites(SiteSettingsCategory.Type.VIRTUAL_REALITY)) { - if (ContentFeatureList.isEnabled(ContentFeatureList.WEBXR_PERMISSIONS_API)) { - // VIRTUAL_REALITY permission is per-origin and per-embedder. - queue.add(new PermissionInfoFetcher(PermissionInfo.Type.VIRTUAL_REALITY)); - } + // VIRTUAL_REALITY permission is per-origin and per-embedder. + queue.add(new PermissionInfoFetcher(PermissionInfo.Type.VIRTUAL_REALITY)); } else if (category.showSites(SiteSettingsCategory.Type.AUGMENTED_REALITY)) { - if (ContentFeatureList.isEnabled(ContentFeatureList.WEBXR_PERMISSIONS_API)) { - // AUGMENTED_REALITY permission is per-origin and per-embedder. - queue.add(new PermissionInfoFetcher(PermissionInfo.Type.AUGMENTED_REALITY)); - } + // AUGMENTED_REALITY permission is per-origin and per-embedder. + queue.add(new PermissionInfoFetcher(PermissionInfo.Type.AUGMENTED_REALITY)); } queue.add(new PermissionsAvailableCallbackRunner(callback)); queue.next(); diff --git a/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreference.java b/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreference.java index a307e6550f1..71b2b84ec8b 100644 --- a/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreference.java +++ b/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreference.java @@ -86,8 +86,18 @@ class WebsitePreference extends ChromeImageViewPreference { private void refresh() { setTitle(mSite.getTitle()); - if (mSite.getEmbedder() == null) return; - + if (mSite.getEmbedder() == null) { + @PermissionInfo.Type + Integer permissionInfoType = + PermissionInfo.getPermissionInfoType(mCategory.getContentSettingsType()); + PermissionInfo permissionInfo = null; + if (permissionInfoType != null + && (permissionInfo = mSite.getPermissionInfo(permissionInfoType)) != null + && permissionInfo.isEmbargoed()) { + setSummary(getContext().getString(R.string.automatically_blocked)); + } + return; + } String subtitleText; if (mSite.representsThirdPartiesOnSite()) { subtitleText = getContext().getString( diff --git a/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreferenceBridge.java b/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreferenceBridge.java index f8c470922aa..b40b44ea050 100644 --- a/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreferenceBridge.java +++ b/chromium/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreferenceBridge.java @@ -77,7 +77,7 @@ public class WebsitePreferenceBridge { } private static void insertInfoIntoList(@PermissionInfo.Type int type, - ArrayList<PermissionInfo> list, String origin, String embedder) { + ArrayList<PermissionInfo> list, String origin, String embedder, boolean isEmbargoed) { if (type == PermissionInfo.Type.CAMERA || type == PermissionInfo.Type.MICROPHONE) { for (PermissionInfo info : list) { if (info.getOrigin().equals(origin) && info.getEmbedder().equals(embedder)) { @@ -85,67 +85,69 @@ public class WebsitePreferenceBridge { } } } - list.add(new PermissionInfo(type, origin, embedder, false)); + list.add(new PermissionInfo(type, origin, embedder, false, isEmbargoed)); } @CalledByNative private static void insertArInfoIntoList( - ArrayList<PermissionInfo> list, String origin, String embedder) { - insertInfoIntoList(PermissionInfo.Type.AUGMENTED_REALITY, list, origin, embedder); + ArrayList<PermissionInfo> list, String origin, String embedder, boolean isEmbargoed) { + insertInfoIntoList( + PermissionInfo.Type.AUGMENTED_REALITY, list, origin, embedder, isEmbargoed); } @CalledByNative private static void insertCameraInfoIntoList( - ArrayList<PermissionInfo> list, String origin, String embedder) { - insertInfoIntoList(PermissionInfo.Type.CAMERA, list, origin, embedder); + ArrayList<PermissionInfo> list, String origin, String embedder, boolean isEmbargoed) { + insertInfoIntoList(PermissionInfo.Type.CAMERA, list, origin, embedder, isEmbargoed); } @CalledByNative private static void insertClipboardInfoIntoList( - ArrayList<PermissionInfo> list, String origin, String embedder) { - insertInfoIntoList(PermissionInfo.Type.CLIPBOARD, list, origin, embedder); + ArrayList<PermissionInfo> list, String origin, String embedder, boolean isEmbargoed) { + insertInfoIntoList(PermissionInfo.Type.CLIPBOARD, list, origin, embedder, isEmbargoed); } @CalledByNative private static void insertGeolocationInfoIntoList( - ArrayList<PermissionInfo> list, String origin, String embedder) { - insertInfoIntoList(PermissionInfo.Type.GEOLOCATION, list, origin, embedder); + ArrayList<PermissionInfo> list, String origin, String embedder, boolean isEmbargoed) { + insertInfoIntoList(PermissionInfo.Type.GEOLOCATION, list, origin, embedder, isEmbargoed); } @CalledByNative private static void insertMicrophoneInfoIntoList( - ArrayList<PermissionInfo> list, String origin, String embedder) { - insertInfoIntoList(PermissionInfo.Type.MICROPHONE, list, origin, embedder); + ArrayList<PermissionInfo> list, String origin, String embedder, boolean isEmbargoed) { + insertInfoIntoList(PermissionInfo.Type.MICROPHONE, list, origin, embedder, isEmbargoed); } @CalledByNative private static void insertMidiInfoIntoList( - ArrayList<PermissionInfo> list, String origin, String embedder) { - insertInfoIntoList(PermissionInfo.Type.MIDI, list, origin, embedder); + ArrayList<PermissionInfo> list, String origin, String embedder, boolean isEmbargoed) { + insertInfoIntoList(PermissionInfo.Type.MIDI, list, origin, embedder, isEmbargoed); } @CalledByNative private static void insertNfcInfoIntoList( - ArrayList<PermissionInfo> list, String origin, String embedder) { - insertInfoIntoList(PermissionInfo.Type.NFC, list, origin, embedder); + ArrayList<PermissionInfo> list, String origin, String embedder, boolean isEmbargoed) { + insertInfoIntoList(PermissionInfo.Type.NFC, list, origin, embedder, isEmbargoed); } @CalledByNative private static void insertNotificationIntoList( - ArrayList<PermissionInfo> list, String origin, String embedder) { - insertInfoIntoList(PermissionInfo.Type.NOTIFICATION, list, origin, embedder); + ArrayList<PermissionInfo> list, String origin, String embedder, boolean isEmbargoed) { + insertInfoIntoList(PermissionInfo.Type.NOTIFICATION, list, origin, embedder, isEmbargoed); } @CalledByNative private static void insertProtectedMediaIdentifierInfoIntoList( - ArrayList<PermissionInfo> list, String origin, String embedder) { - insertInfoIntoList(PermissionInfo.Type.PROTECTED_MEDIA_IDENTIFIER, list, origin, embedder); + ArrayList<PermissionInfo> list, String origin, String embedder, boolean isEmbargoed) { + insertInfoIntoList(PermissionInfo.Type.PROTECTED_MEDIA_IDENTIFIER, list, origin, embedder, + isEmbargoed); } @CalledByNative private static void insertSensorsInfoIntoList( - ArrayList<PermissionInfo> list, String origin, String embedder) { - insertInfoIntoList(PermissionInfo.Type.SENSORS, list, origin, embedder); + ArrayList<PermissionInfo> list, String origin, String embedder, boolean isEmbargoed) { + insertInfoIntoList(PermissionInfo.Type.SENSORS, list, origin, embedder, isEmbargoed); } @CalledByNative @@ -156,8 +158,9 @@ public class WebsitePreferenceBridge { @CalledByNative private static void insertVrInfoIntoList( - ArrayList<PermissionInfo> list, String origin, String embedder) { - insertInfoIntoList(PermissionInfo.Type.VIRTUAL_REALITY, list, origin, embedder); + ArrayList<PermissionInfo> list, String origin, String embedder, boolean isEmbargoed) { + insertInfoIntoList( + PermissionInfo.Type.VIRTUAL_REALITY, list, origin, embedder, isEmbargoed); } @CalledByNative @@ -354,6 +357,7 @@ public class WebsitePreferenceBridge { switch (contentSettingsType) { case ContentSettingsType.ADS: + case ContentSettingsType.BLUETOOTH_GUARD: case ContentSettingsType.BLUETOOTH_SCANNING: case ContentSettingsType.JAVASCRIPT: case ContentSettingsType.POPUPS: @@ -422,6 +426,9 @@ public class WebsitePreferenceBridge { case ContentSettingsType.POPUPS: // Returns true if websites are allowed to request permission to access USB devices. case ContentSettingsType.USB_GUARD: + // Returns true if websites are allowed to request permission to access Bluetooth + // devices. + case ContentSettingsType.BLUETOOTH_GUARD: case ContentSettingsType.BLUETOOTH_SCANNING: return isContentSettingEnabled(browserContextHandle, contentSettingsType); case ContentSettingsType.AR: diff --git a/chromium/components/browser_ui/site_settings/android/javatests/src/org/chromium/components/browser_ui/site_settings/WebsiteAddressTest.java b/chromium/components/browser_ui/site_settings/android/javatests/src/org/chromium/components/browser_ui/site_settings/WebsiteAddressTest.java index a799614c5a5..bf9d8e381a7 100644 --- a/chromium/components/browser_ui/site_settings/android/javatests/src/org/chromium/components/browser_ui/site_settings/WebsiteAddressTest.java +++ b/chromium/components/browser_ui/site_settings/android/javatests/src/org/chromium/components/browser_ui/site_settings/WebsiteAddressTest.java @@ -4,7 +4,7 @@ package org.chromium.components.browser_ui.site_settings; -import android.support.test.filters.SmallTest; +import androidx.test.filters.SmallTest; import org.junit.Assert; import org.junit.Before; diff --git a/chromium/components/browser_ui/site_settings/android/site_settings_feature_list.cc b/chromium/components/browser_ui/site_settings/android/site_settings_feature_list.cc index ce85744a8b5..70c94e7c417 100644 --- a/chromium/components/browser_ui/site_settings/android/site_settings_feature_list.cc +++ b/chromium/components/browser_ui/site_settings/android/site_settings_feature_list.cc @@ -4,6 +4,7 @@ #include "base/android/jni_string.h" #include "base/feature_list.h" +#include "base/notreached.h" #include "base/stl_util.h" #include "components/browser_ui/site_settings/android/features.h" diff --git a/chromium/components/browser_ui/site_settings/android/storage_info_fetcher.cc b/chromium/components/browser_ui/site_settings/android/storage_info_fetcher.cc index f11a27d6198..14ff1dfe39c 100644 --- a/chromium/components/browser_ui/site_settings/android/storage_info_fetcher.cc +++ b/chromium/components/browser_ui/site_settings/android/storage_info_fetcher.cc @@ -5,7 +5,6 @@ #include "components/browser_ui/site_settings/android/storage_info_fetcher.h" #include "base/bind.h" -#include "base/task/post_task.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" @@ -33,8 +32,8 @@ void StorageInfoFetcher::FetchStorageInfo(FetchCallback fetch_callback) { // QuotaManager must be called on IO thread, but the callback must then be // called on the UI thread. - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + content::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce( &StorageInfoFetcher::GetUsageInfo, this, base::BindOnce(&StorageInfoFetcher::OnGetUsageInfoInternal, this))); @@ -49,8 +48,8 @@ void StorageInfoFetcher::ClearStorage(const std::string& host, clear_callback_ = std::move(clear_callback); type_to_delete_ = type; - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + content::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce( &storage::QuotaManager::DeleteHostData, quota_manager_, host, type, storage::AllQuotaClientTypes(), @@ -68,8 +67,8 @@ void StorageInfoFetcher::OnGetUsageInfoInternal( entries_ = std::move(entries); - base::PostTask(FROM_HERE, {BrowserThread::UI}, - base::BindOnce(&StorageInfoFetcher::OnFetchCompleted, this)); + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&StorageInfoFetcher::OnFetchCompleted, this)); } void StorageInfoFetcher::OnFetchCompleted() { @@ -86,8 +85,8 @@ void StorageInfoFetcher::OnUsageClearedInternal( quota_manager_->ResetUsageTracker(type_to_delete_); - base::PostTask( - FROM_HERE, {BrowserThread::UI}, + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&StorageInfoFetcher::OnClearCompleted, this, code)); } diff --git a/chromium/components/browser_ui/site_settings/android/website_preference_bridge.cc b/chromium/components/browser_ui/site_settings/android/website_preference_bridge.cc index 8f279ee726e..bfc9188b16c 100644 --- a/chromium/components/browser_ui/site_settings/android/website_preference_bridge.cc +++ b/chromium/components/browser_ui/site_settings/android/website_preference_bridge.cc @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <jni.h> #include <algorithm> #include <string> #include <vector> @@ -125,7 +126,8 @@ typedef void (*InfoListInsertionFunction)( JNIEnv*, const base::android::JavaRef<jobject>&, const base::android::JavaRef<jstring>&, - const base::android::JavaRef<jstring>&); + const base::android::JavaRef<jstring>&, + jboolean); void GetOrigins(JNIEnv* env, const JavaParamRef<jobject>& jbrowser_context_handle, @@ -166,7 +168,8 @@ void GetOrigins(JNIEnv* env, jembedder = ConvertUTF8ToJavaString(env, embedder); seen_origins.push_back(origin); - insertionFunc(env, list, ConvertOriginToJavaString(env, origin), jembedder); + insertionFunc(env, list, ConvertOriginToJavaString(env, origin), jembedder, + /*is_embargoed=*/false); } // Add any origins which have a default content setting value (thus skipped @@ -188,7 +191,7 @@ void GetOrigins(JNIEnv* env, .content_setting == CONTENT_SETTING_BLOCK) { seen_origins.push_back(origin); insertionFunc(env, list, ConvertOriginToJavaString(env, origin), - jembedder); + jembedder, /*is_embargoed=*/true); } } } @@ -1039,7 +1042,8 @@ static jboolean JNI_WebsitePreferenceBridge_IsContentSettingEnabled( type == ContentSettingsType::ADS || type == ContentSettingsType::CLIPBOARD_READ_WRITE || type == ContentSettingsType::USB_GUARD || - type == ContentSettingsType::BLUETOOTH_SCANNING); + type == ContentSettingsType::BLUETOOTH_SCANNING || + type == ContentSettingsType::BLUETOOTH_GUARD); return GetBooleanForContentSetting(jbrowser_context_handle, type); } @@ -1057,12 +1061,14 @@ static void JNI_WebsitePreferenceBridge_SetContentSettingEnabled( type == ContentSettingsType::POPUPS || type == ContentSettingsType::ADS || type == ContentSettingsType::USB_GUARD || - type == ContentSettingsType::BLUETOOTH_SCANNING); + type == ContentSettingsType::BLUETOOTH_SCANNING || + type == ContentSettingsType::BLUETOOTH_GUARD); ContentSetting value = CONTENT_SETTING_BLOCK; if (allow) { if (type == ContentSettingsType::USB_GUARD || - type == ContentSettingsType::BLUETOOTH_SCANNING) { + type == ContentSettingsType::BLUETOOTH_SCANNING || + type == ContentSettingsType::BLUETOOTH_GUARD) { value = CONTENT_SETTING_ASK; } else { value = CONTENT_SETTING_ALLOW; diff --git a/chromium/components/browser_ui/strings/android/browser_ui_strings.grd b/chromium/components/browser_ui/strings/android/browser_ui_strings.grd index 7f2795e9058..66257c44a71 100644 --- a/chromium/components/browser_ui/strings/android/browser_ui_strings.grd +++ b/chromium/components/browser_ui/strings/android/browser_ui_strings.grd @@ -192,6 +192,9 @@ <message name="IDS_DETAILS_LINK" desc="In 1) Settings > Clean up computer (desktop), a link to open details of incompatible applications. In 2) Settings > Lite mode (mobile), static title for data usage breakdown." meaning="Short for 'view details'. Link; static title."> Details </message> + <message name="IDS_CHANGE_LINK" desc="Any link text giving option to the user to edit some settings. [CHAR-LIMIT=20]"> + Change + </message> <message name="IDS_DONE" desc="Label for a button to save a change or finish editing data. Used in multiple contexts. [CHAR-LIMIT=20]"> Done </message> @@ -255,6 +258,9 @@ <message name="IDS_ADD" desc="Prompt for the user to add something, like a new address. [CHAR-LIMIT=20]"> Add </message> + <message name="IDS_CHANGE" desc="Prompt for the user to change something. [CHAR-LIMIT=20]"> + Change + </message> <message name="IDS_SHARE" desc="Content description for a button to share item(s). [CHAR-LIMIT=20]"> Share </message> @@ -378,6 +384,9 @@ <message name="IDS_MENU_HELP" desc="Menu item for opening the help page. [CHAR-LIMIT=27]"> Help & feedback </message> + <message name="IDS_AUTOMATICALLY_BLOCKED" desc="Description displayed next to an origin when it was placed under embargo by Chrome. This indicates to the user that the origin is blocked automatically instead of being the result of the user's decision."> + Automatically blocked + </message> <!-- Downloads UI --> <message name="IDS_DOWNLOAD_NOTIFICATION_CANCEL_BUTTON" desc="Text on the button that cancels a download."> @@ -435,6 +444,9 @@ <message name="IDS_PAGE_INFO_PREVIEW_MESSAGE" desc="This text is displayed in the page info bubble when the currently viewed page has been modified by Google to be a lighter and faster version of the original page. The word 'Lite' should match the translation in TC ID 1019734090540434451"> Lite page provided by Google </message> + <message name="IDS_PAGE_INFO_LITE_MODE_HTTPS_IMAGE_COMPRESSION" desc="This text is displayed in the page info bubble when the currently viewed page has https images that were optimized by Google"> + To save you data, this page's images have been optimized by Google. + </message> <message name="IDS_PAGE_INFO_OPEN_ONLINE_BUTTON" desc="Text in the button that attempts to open an online version of the offline website displayed in the tab."> Open Online </message> @@ -472,47 +484,90 @@ Blocked for current search engine </message> - <message name="IDS_COOKIES_TITLE" desc="Title for the Cookies settings screen [CHAR-LIMIT=32]"> - Cookies - </message> + <message name="IDS_COOKIES_TITLE" desc="Title for the Cookies settings screen [CHAR-LIMIT=32]"> + Cookies + </message> + + <!-- Media Capture and Streams --> + <message name="IDS_MEDIA_CAPTURE_NOTIFICATION_APP_NAME_SEPARATOR" desc="A separator between the app name and notification message."> + <ph name="APP_NAME">%1$s<ex>Chrome</ex></ph> - <ph name="NOTIFICATION_MESSAGE">%2$s<ex>Accessing video input</ex></ph> + </message> + <message name="IDS_VIDEO_CAPTURE_NOTIFICATION_TITLE" desc="Text to be shown as a notification when a WebRTC video call is in progress."> + A site is using your camera + </message> + <message name="IDS_AUDIO_CAPTURE_NOTIFICATION_TITLE" desc="Text to be shown as a notification when a WebRTC audio call is in progress"> + A site is using your microphone + </message> + <message name="IDS_VIDEO_AUDIO_CAPTURE_NOTIFICATION_TITLE" desc="Text to be shown as a notification when a WebRTC video and audio call is in progress"> + A site is using your camera and microphone + </message> + <message name="IDS_MEDIA_CAPTURE_NOTIFICATION_CONTENT_TEXT" desc="Url of the current tab. The notification will display this text for the user to identify the tab to return to."> + Tap to return to <ph name="URL_OF_THE_CURRENT_TAB">%1$s<ex>https://apprtc.appspot.com</ex></ph> + </message> + <message name="IDS_MEDIA_CAPTURE_NOTIFICATION_CONTENT_TEXT_INCOGNITO" desc="The notification will display this text for the user to return to the incognito tab which has created the notification."> + Tap to return to the site + </message> + <message name="IDS_ACCESSIBILITY_STOP" desc="Accessible name for a button that stops playing or recording media."> + Stop + </message> + <message name="IDS_NOTIFICATION_INCOGNITO_TAB" desc="Text used as notifications source when the notification is from incognito tabs."> + Incognito tab + </message> + <message name="IDS_NOTIFICATION_CATEGORY_COMPLETED_DOWNLOADS" desc="Label for completed download notifications, within a list of notification categories. [CHAR-LIMIT=32]"> + Completed downloads + </message> + <message name="IDS_NOTIFICATION_CATEGORY_DOWNLOADS" desc="Label for notifications shown when something is downloading, within a list of notification categories. [CHAR-LIMIT=32]"> + Active downloads + </message> + <message name="IDS_NOTIFICATION_CATEGORY_MEDIA_PLAYBACK" desc="Label for media playback notifications, within a list of notification categories. [CHAR-LIMIT=32]"> + Playing media + </message> + <message name="IDS_NOTIFICATION_CATEGORY_WEBRTC_CAM_AND_MIC" desc="Label for notifications shown when media is being recorded from a camera or microphone, within a list of notification categories. [CHAR-LIMIT=32]"> + Camera and microphone use + </message> + <message name="IDS_SCREEN_CAPTURE_NOTIFICATION_TITLE" desc="Text to be shown as a notification when screen capture is in progress."> + Sharing your screen + </message> + + <message name="IDS_SHARE_LINK_CHOOSER_TITLE" desc="title for the share dialog when sharing the current address [CHAR-LIMIT=27]"> + Share via + </message> - <!-- Media Capture and Streams --> - <message name="IDS_MEDIA_CAPTURE_NOTIFICATION_APP_NAME_SEPARATOR" desc="A separator between the app name and notification message."> - <ph name="APP_NAME">%1$s<ex>Chrome</ex></ph> - <ph name="NOTIFICATION_MESSAGE">%2$s<ex>Accessing video input</ex></ph> - </message> - <message name="IDS_VIDEO_CAPTURE_NOTIFICATION_TITLE" desc="Text to be shown as a notification when a WebRTC video call is in progress."> - A site is using your camera - </message> - <message name="IDS_AUDIO_CAPTURE_NOTIFICATION_TITLE" desc="Text to be shown as a notification when a WebRTC audio call is in progress"> - A site is using your microphone - </message> - <message name="IDS_VIDEO_AUDIO_CAPTURE_NOTIFICATION_TITLE" desc="Text to be shown as a notification when a WebRTC video and audio call is in progress"> - A site is using your camera and microphone - </message> - <message name="IDS_MEDIA_CAPTURE_NOTIFICATION_CONTENT_TEXT" desc="Url of the current tab. The notification will display this text for the user to identify the tab to return to."> - Tap to return to <ph name="URL_OF_THE_CURRENT_TAB">%1$s<ex>https://apprtc.appspot.com</ex></ph> - </message> - <message name="IDS_MEDIA_CAPTURE_NOTIFICATION_CONTENT_TEXT_INCOGNITO" desc="The notification will display this text for the user to return to the incognito tab which has created the notification."> - Tap to return to the site - </message> - <message name="IDS_ACCESSIBILITY_STOP" desc="Accessible name for a button that stops playing or recording media."> - Stop - </message> - <message name="IDS_NOTIFICATION_INCOGNITO_TAB" desc="Text used as notifications source when the notification is from incognito tabs."> - Incognito tab - </message> - <message name="IDS_NOTIFICATION_CATEGORY_COMPLETED_DOWNLOADS" desc="Label for completed download notifications, within a list of notification categories. [CHAR-LIMIT=32]"> - Completed downloads - </message> - <message name="IDS_NOTIFICATION_CATEGORY_DOWNLOADS" desc="Label for notifications shown when something is downloading, within a list of notification categories. [CHAR-LIMIT=32]"> - Active downloads - </message> - <message name="IDS_NOTIFICATION_CATEGORY_WEBRTC_CAM_AND_MIC" desc="Label for notifications shown when media is being recorded from a camera or microphone, within a list of notification categories. [CHAR-LIMIT=32]"> - Camera and microphone use - </message> - <message name="IDS_SCREEN_CAPTURE_NOTIFICATION_TITLE" desc="Text to be shown as a notification when screen capture is in progress."> - Sharing your screen - </message> + <!-- Messages for media playback (casting, MediaSession, etc) --> + <message name="IDS_ACCESSIBILITY_PLAY" desc="The play button that starts playing the media."> + Play + </message> + <message name="IDS_ACCESSIBILITY_PAUSE" desc="The pause button that pauses playing the media."> + Pause + </message> + <message name="IDS_ACCESSIBILITY_PREVIOUS_TRACK" desc="The previous track button that switches media to the previous track."> + Previous track + </message> + <message name="IDS_ACCESSIBILITY_NEXT_TRACK" desc="The next track button that switches media to the next track."> + Next track + </message> + <message name="IDS_ACCESSIBILITY_SEEK_FORWARD" desc="The seek forward button that seeks media to a later position."> + Seek forward + </message> + <message name="IDS_ACCESSIBILITY_SEEK_BACKWARD" desc="The seek backward button that seeks media to an earlier position."> + Seek backward + </message> + <message name="IDS_MEDIA_NOTIFICATION_INCOGNITO" desc="Text used as a placeholder for a media notification about playing media, when notification is shown from incognito tab."> + A site is playing media + </message> + + <!-- BottomSheet --> + <message name="IDS_BOTTOM_SHEET_ACCESSIBILITY_DESCRIPTION" desc="Accessibility string read when the bottom sheet is focused informing the user that the sheet can be closed by swiping down."> + Swipe down to close. + </message> + + <!-- Client certificate selection failure strings. --> + <message name="IDS_CLIENT_CERT_UNSUPPORTED_TITLE" desc="Title of a dialog box for when the operating system does not support client SSL certificate selection" formatter_data="android_java"> + Unable to select certificate. + </message> + <message name="IDS_CLIENT_CERT_UNSUPPORTED_MESSAGE" desc="The message in a dialog box for when the operating system does not support client SSL certificate selection" formatter_data="android_java"> + Client side certificate selection is not supported by the operating system. + </message> </messages> </release> diff --git a/chromium/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_PAGE_INFO_LITE_MODE_HTTPS_IMAGE_COMPRESSION.png.sha1 b/chromium/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_PAGE_INFO_LITE_MODE_HTTPS_IMAGE_COMPRESSION.png.sha1 new file mode 100644 index 00000000000..a86aeb47184 --- /dev/null +++ b/chromium/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_PAGE_INFO_LITE_MODE_HTTPS_IMAGE_COMPRESSION.png.sha1 @@ -0,0 +1 @@ +212a781d980587ffb65c0d71cc96ce0bdb3832bb
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/browser_ui_strings_grd/scheduled_for_later.png.sha1 b/chromium/components/browser_ui/strings/android/browser_ui_strings_grd/scheduled_for_later.png.sha1 new file mode 100644 index 00000000000..1670826c602 --- /dev/null +++ b/chromium/components/browser_ui/strings/android/browser_ui_strings_grd/scheduled_for_later.png.sha1 @@ -0,0 +1 @@ +611e2667da59528924617439be19de090c2c8f32
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/site_settings.grdp b/chromium/components/browser_ui/strings/android/site_settings.grdp index 037a8dacd6e..f1cc5249032 100644 --- a/chromium/components/browser_ui/strings/android/site_settings.grdp +++ b/chromium/components/browser_ui/strings/android/site_settings.grdp @@ -269,6 +269,18 @@ <!-- Bluetooth --> + <message name="IDS_WEBSITE_SETTINGS_CATEGORY_BLUETOOTH_ASK" desc="Summary text explaining that the Bluetooth permission is set to ask the user for permission to access individual devices. To be shown in the list of permission categories."> + Ask before allowing sites to connect to a device (recommended) + </message> + <message name="IDS_WEBSITE_SETTINGS_CATEGORY_BLUETOOTH_BLOCKED" desc="Summary text explaining that the Bluetooth permission is set to block all requests for access to devices. To be shown in the list of permission categories."> + Block sites from connecting to devices + </message> + <message name="IDS_WEBSITE_SETTINGS_BLUETOOTH" desc="Title for Bluetooth settings, which control which of the user's Bluetooth devices can be accessed from websites."> + Bluetooth + </message> + + <!-- Bluetooth Scanning --> + <message name="IDS_WEBSITE_SETTINGS_CATEGORY_BLUETOOTH_SCANNING_ASK" desc="Summary text explaining that the Bluetooth scanning permission is set to ask the user for permission to do Bluetooth scanning. To be shown in the list of permission categories."> Ask when a site wants to discover nearby Bluetooth devices (recommended) </message> diff --git a/chromium/components/browser_ui/strings/android/site_settings_grdp/IDS_WEBSITE_SETTINGS_BLUETOOTH.png.sha1 b/chromium/components/browser_ui/strings/android/site_settings_grdp/IDS_WEBSITE_SETTINGS_BLUETOOTH.png.sha1 new file mode 100644 index 00000000000..c3deb3069de --- /dev/null +++ b/chromium/components/browser_ui/strings/android/site_settings_grdp/IDS_WEBSITE_SETTINGS_BLUETOOTH.png.sha1 @@ -0,0 +1 @@ +5c2db6cbf8fa317258407d2947394406dae689e3
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/site_settings_grdp/IDS_WEBSITE_SETTINGS_CATEGORY_BLUETOOTH_ASK.png.sha1 b/chromium/components/browser_ui/strings/android/site_settings_grdp/IDS_WEBSITE_SETTINGS_CATEGORY_BLUETOOTH_ASK.png.sha1 new file mode 100644 index 00000000000..303690df77c --- /dev/null +++ b/chromium/components/browser_ui/strings/android/site_settings_grdp/IDS_WEBSITE_SETTINGS_CATEGORY_BLUETOOTH_ASK.png.sha1 @@ -0,0 +1 @@ +1bba94995f4b58a0f16751fda0a6fcdc38282c43
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/site_settings_grdp/IDS_WEBSITE_SETTINGS_CATEGORY_BLUETOOTH_BLOCKED.png.sha1 b/chromium/components/browser_ui/strings/android/site_settings_grdp/IDS_WEBSITE_SETTINGS_CATEGORY_BLUETOOTH_BLOCKED.png.sha1 new file mode 100644 index 00000000000..4f13c68d7e5 --- /dev/null +++ b/chromium/components/browser_ui/strings/android/site_settings_grdp/IDS_WEBSITE_SETTINGS_CATEGORY_BLUETOOTH_BLOCKED.png.sha1 @@ -0,0 +1 @@ +2645ff62b62780091b64d3380eb84bd92bd373b6
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_af.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_af.xtb index 57f8b531a20..f5f78abdc12 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_af.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_af.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Volgende</translation> <translation id="1242008676835033345">Ingebed op <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Stop</translation> +<translation id="1289742167380433257">Hierdie bladsy se prente is geoptimeer om vir jou data te bespaar.</translation> <translation id="129382876167171263">Lêers wat deur webwerwe gestoor is, verskyn hier</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> – <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Werf <ph name="SITE_NAME" /> bygevoeg</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Vra voordat werwe toegelaat word om 'n 3D-kaart van jou omgewing te skep of kameraposisie na te spoor (aanbeveel)</translation> <translation id="2212565012507486665">Laat webkoekies toe</translation> <translation id="2289270750774289114">Vra wanneer 'n werf Bluetooth-toestelle in die omtrek wil ontdek (aanbeveel)</translation> +<translation id="2315043854645842844">Bedryfstelsel steun nie die sertifikaat wat die kliënt gekies het nie.</translation> <translation id="2359808026110333948">Gaan voort</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">Aflaai is voltooi <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Gekopieer</translation> <translation id="2822354292072154809">Is jy seker jy wil alle werftoestemmings vir <ph name="CHOSEN_OBJECT_NAME" /> terugstel?</translation> <translation id="2870560284913253234">Werf</translation> +<translation id="2874939134665556319">Vorige snit</translation> <translation id="2910701580606108292">Vra voordat werwe toegelaat word om beskermde inhoud te speel</translation> <translation id="2913331724188855103">Laat werwe toe om webkoekiedata te stoor en te lees (aanbeveel)</translation> <translation id="2968755619301702150">Sertifikaatbekyker</translation> <translation id="300526633675317032">Dit sal al <ph name="SIZE_IN_KB" /> se webwerfberging uitvee.</translation> +<translation id="301521992641321250">Outomaties geblokkeer</translation> <translation id="3115898365077584848">Wys inligting</translation> <translation id="3123473560110926937">Geblokkeer op sommige werwe</translation> <translation id="3190152372525844641">Skakel toestemmings vir Chrome aan in <ph name="BEGIN_LINK" />Android-instellings<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Agtergrondsinkronisering</translation> <translation id="3822502789641063741">Vee werfberging uit?</translation> <translation id="385051799172605136">Terug</translation> +<translation id="3859306556332390985">Soek vorentoe</translation> <translation id="3955193568934677022">Laat werwe toe om beskermde inhoud te speel (aanbeveel)</translation> <translation id="3987993985790029246">Kopieer skakel</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> van ?</translation> <translation id="4002066346123236978">Titel</translation> <translation id="4008040567710660924">Laat webkoekies vir 'n spesifieke werf toe.</translation> +<translation id="4046123991198612571">Volgende snit</translation> <translation id="4165986682804962316">Werfinstellings</translation> <translation id="4226663524361240545">Kennisgewings kan die toestel laat vibreer</translation> <translation id="4242533952199664413">Maak instellings oop</translation> <translation id="4259722352634471385">Navigasie is geblokkeer: <ph name="URL" /></translation> <translation id="4278390842282768270">Toegelaat</translation> +<translation id="429312253194641664">'n Werf speel tans media</translation> <translation id="4433925000917964731">Ligte bladsy deur Google verskaf</translation> <translation id="4434045419905280838">Opspringers en herleidings</translation> <translation id="445467742685312942">Laat werwe toe om beskermde inhoud te speel</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Herroep alle toestemmings vir toestel</translation> <translation id="4964199952259983386">Skakel ook kamera in <ph name="BEGIN_LINK" />Android-instellings<ph name="END_LINK" /> aan sodat Chrome AR kan gebruik.</translation> <translation id="497421865427891073">Gaan vorentoe</translation> +<translation id="4996978546172906250">Deel via</translation> <translation id="5039804452771397117">Laat toe</translation> <translation id="5048398596102334565">Laat werwe toegang tot bewegingsensors toe (aanbeveel)</translation> <translation id="5063480226653192405">Gebruik</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Vee uit</translation> <translation id="6697925417670533197">Aktiewe aflaaie</translation> <translation id="6746124502594467657">Skuif af</translation> +<translation id="6766622839693428701">Swiep ondertoe om toe te maak</translation> <translation id="6782111308708962316">Keer derdeparty-webwerwe om webkoekiedata te stoor en te lees</translation> +<translation id="6790428901817661496">Speel</translation> <translation id="6818926723028410516">Kies items</translation> <translation id="6864395892908308021">Hierdie toestel kan nie NFC lees nie</translation> <translation id="6910211073230771657">Uitgevee</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">'n Werf gebruik tans jou kamera</translation> <translation id="7817023149356982970">Jy sal op hierdie werf afgemeld word.</translation> <translation id="7828557259026017104">Webkoekies is lêers wat geskep word deur webwerwe wat jy besoek. Werwe kan hulle gebruik om jou voorkeure te onthou. Derdepartywebkoekies word deur ander werwe geskep. Hierdie werwe besit van die inhoud, soos advertensies of prente, wat jy sien op die webbladsy wat jy besoek.</translation> +<translation id="7835852323729233924">Speel tans media</translation> <translation id="7846076177841592234">Kanselleer keuse</translation> <translation id="7846621471902887024">Jy sal op alle werwe afgemeld word.</translation> <translation id="7882806643839505685">Laat klank toe vir 'n spesifieke werf.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Is jy seker dat jy alle plaaslike data, insluitend webkoekies, wil uitvee en alle toestemmings vir hierdie webwerf wil terugstel?</translation> <translation id="8007176423574883786">Afgeskakel vir hierdie toestel</translation> <translation id="802154636333426148">Kon nie aflaai nie</translation> +<translation id="8068648041423924542">Kan nie sertifikaat kies nie.</translation> <translation id="8087000398470557479">Hierdie inhoud kom van <ph name="DOMAIN_NAME" /> af, afgelewer deur Google.</translation> <translation id="8116925261070264013">Gedemp</translation> <translation id="8131740175452115882">Bevestig</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">'n Werf gebruik tans jou kamera en mikrofoon</translation> <translation id="8380167699614421159">Hierdie werf wys indringerige of misleidende advertensies</translation> <translation id="8394832520002899662">Tik om na werf terug te keer</translation> +<translation id="8425213833346101688">Verander</translation> +<translation id="8441146129660941386">Soek agtertoe</translation> <translation id="8447861592752582886">Herroep toesteltoestemming</translation> <translation id="8463851957836045671">Werf is vinnig</translation> <translation id="851751545965956758">Keer dat werwe aan toestelle koppel</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Blokkeer webkoekies vir 'n spesifieke werf.</translation> <translation id="8959122750345127698">Navigasie is onbereikbaar: <ph name="URL" /></translation> <translation id="9019902583201351841">Deur jou ouers bestuur</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Toegang tot jou mikrofoon</translation> <translation id="965817943346481315">Blokkeer as werf indringerige of misleidende advertensies wys (aanbeveel)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_am.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_am.xtb index b0bba485b3b..aecb9f7689c 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_am.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_am.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">ቀጣይ</translation> <translation id="1242008676835033345"><ph name="WEBSITE_URL" /> ላይ ተካትቷል</translation> <translation id="1272079795634619415">አቁም</translation> +<translation id="1289742167380433257">ውሂብ እንዲቆጥብልዎ የዚህ ገጽ ምስሎች በGoogle እንዲተቡ ተደርገዋል።</translation> <translation id="129382876167171263">በድር ጣቢያዎች የተቀመጡ ፋይሎች እዚህ ይታያሉ</translation> <translation id="1364532808393826295"><ph name="APP_NAME" />፣ <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676"><ph name="SITE_NAME" /> ጣቢያ ተክሏል</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">ጣቢያዎች የዙሪያዎ የ3ል ካርታ እንዲፈጥሩ ወይም የካሜራ ቦታን እንዲከታተል ከመፍቀድ በፊት ጠይቅ (የሚመከር)</translation> <translation id="2212565012507486665">ኩኪዎችን ፍቀድ</translation> <translation id="2289270750774289114">አንድ ጣቢያ በአቅራቢያ ያሉ ብሉቱዝ መሣሪያዎችን ፈልጎ ለማግኘት ሲፈልግ ጠይቅ (የሚመከር)</translation> +<translation id="2315043854645842844">የደንበኛ ወገን ዕውቅና ማረጋገጫ ምርጫ በስርዓተ-ክወናው አይደገፍም።</translation> <translation id="2359808026110333948">ቀጥል</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> ሜባ</translation> <translation id="2434158240863470628">ማውረድ ተጠናቅቋል <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">ተቀድቷል</translation> <translation id="2822354292072154809">እርግጠኛ ነዎት ሁሉንም የ<ph name="CHOSEN_OBJECT_NAME" /> ጣቢያ ፈቃዶችን ዳግም ማስጀመር ይፈልጋሉ?</translation> <translation id="2870560284913253234">ጣቢያ</translation> +<translation id="2874939134665556319">ቀዳሚ ትራክ</translation> <translation id="2910701580606108292">ጣቢያዎች ጥበቃ የሚደረግለትን ይዘትን እንዲያጫውቱ ከመፍቀድ በፊት ጠይቅ</translation> <translation id="2913331724188855103">ጣቢያዎች የኩኪ ውሂብ እንዲያስቀምጡ እና እንዲያነቡ ይፍቀዱ (የሚመከር)</translation> <translation id="2968755619301702150">የእውቅና ማረጋገጫ መመልከቻ</translation> <translation id="300526633675317032">ይህ ሁሉንም <ph name="SIZE_IN_KB" /> የድር ጣቢያ ማከማቻ ያጸዳል።</translation> +<translation id="301521992641321250">በራስ-ሰር ታግዷል</translation> <translation id="3115898365077584848">መረጃ አሳይ</translation> <translation id="3123473560110926937">በአንዳንድ ጣቢያዎች ላይ ታግዷል</translation> <translation id="3190152372525844641">በ<ph name="BEGIN_LINK" />Android ቅንብሮች<ph name="END_LINK" /> ውስጥ ፍቃዶችን ለChrome ያብሩ።</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">የዳራ ስምረት</translation> <translation id="3822502789641063741">የጣቢያ ማከማቻ ይጽዳ?</translation> <translation id="385051799172605136">ተመለስ</translation> +<translation id="3859306556332390985">ወደፊት ፈልግ</translation> <translation id="3955193568934677022">ጥበቃ የሚደረግበትን ይዘት እንዲያጫውቱ ለጣቢያዎች ፍቀድ (የሚመከር)</translation> <translation id="3987993985790029246">አገናኝ ቅዳ</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">ርዕስ</translation> <translation id="4008040567710660924">የተወሰነ ጣቢያ ኩኪዎችን ፍቀድ።</translation> +<translation id="4046123991198612571">ቀጣይ ትራክ</translation> <translation id="4165986682804962316">የጣቢያ ቅንብሮች</translation> <translation id="4226663524361240545">ማሳወቂያዎች መሣሪያውን እንዲነዝር ሊያደርጉት ይችላሉ</translation> <translation id="4242533952199664413">ቅንብሮችን ክፈት</translation> <translation id="4259722352634471385">ዳሰሳ ታግዷል፦ <ph name="URL" /></translation> <translation id="4278390842282768270">ተፈቅዷል</translation> +<translation id="429312253194641664">አንድ ጣቢያ ሚዲያን በማጫወት ላይ ነው</translation> <translation id="4433925000917964731">ቀላል ገጹ በGoogle ቀርቧል።</translation> <translation id="4434045419905280838">ብቅ-ባዮች እና አቅጣጫ ማዞሮች</translation> <translation id="445467742685312942">ጣቢያዎች የተጠበቀ ይዘትን እንዲያጫውት ይፍቀዱ</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">ሁሉንም የመሣሪያ ፈቃዶች ይሻሩ</translation> <translation id="4964199952259983386">Chrome ኤአርን እንዲጠቀም ለማስቻል፣ እንዲሁም በ<ph name="BEGIN_LINK" />የAndroid ቅንብሮች<ph name="END_LINK" /> ውስጥ ካሜራውን ያብሩ።</translation> <translation id="497421865427891073">ወደ ፊት ሂድ</translation> +<translation id="4996978546172906250">ያጋሩ በ</translation> <translation id="5039804452771397117">ፍቀድ</translation> <translation id="5048398596102334565">ጣቢያዎች የእንቅስቃሴ ዳሳሾችን እንዲደርሱባቸው ይፍቀዱ (የሚመከር)</translation> <translation id="5063480226653192405">አጠቃቀም</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">አጽዳ</translation> <translation id="6697925417670533197">ንቁ ውርዶች</translation> <translation id="6746124502594467657">ወደታች አውርድ</translation> +<translation id="6766622839693428701">ለመዝጋት ወደታች ያንሸራትቱ።</translation> <translation id="6782111308708962316">የሦስተኛ ወገን ድር ጣቢያዎች የኩኪ ውሂብን እንዳያስቀምጡ እና እንዳያነብቡ ከልክል</translation> +<translation id="6790428901817661496">አጫውት</translation> <translation id="6818926723028410516">ንጥሎችን ይምረጡ</translation> <translation id="6864395892908308021">ይህ መሣሪያ NFCን ማንበብ አይችልም</translation> <translation id="6910211073230771657">ተሰርዟል</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">አንድ ጣቢያ ካሜራዎን እየተጠቀመ ነው</translation> <translation id="7817023149356982970">ከዚህ ጣቢያ ዘግተው እንዲወጡ ይደረጋሉ።</translation> <translation id="7828557259026017104">ኩኪዎች እርስዎ በሚጎበኟቸው ድር ጣቢያዎች የሚፈጠሩ ፋይሎች ናቸው። ጣቢያዎች የእርስዎን ምርጫዎች ለማስታወስ ይጠቀሙባቸዋል። የሦስተኛ ወገን ኩኪዎች በሌሎች ጣቢያዎች የሚፈጠሩ ናቸው። እነዚህ ጣቢያዎች እንደ ማስታወቂያዎች ወይም ምስሎች ያሉ እርስዎ በሚጎበኙት ድረ-ገጽ ላይ ያለ ይዘትን በባለቤትነት የያዙ ናቸው።</translation> +<translation id="7835852323729233924">ሚዲያን በማጫወት ላይ</translation> <translation id="7846076177841592234">ምርጫ ሰርዝ</translation> <translation id="7846621471902887024">ከሁሉም ጣቢያዎች ዘግተው እንዲወጡ ይደረጋሉ።</translation> <translation id="7882806643839505685">ለተወሰነ ጣቢያ ድምጽ ፍቀድ።</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">እርግጠኛ ነዎት ለዚህ ጣቢያ ኩኪዎችንም ጨምሮ ሁሉንም አካባቢያዊ ውሂብ ማጽዳት እና ሁሉም ፍቃዶችን ዳግም ማስጀመር ይፈልጋሉ?</translation> <translation id="8007176423574883786">ለዚህ መሣሪያ ጠፍቷል</translation> <translation id="802154636333426148">ማውረድ አልተሳካም</translation> +<translation id="8068648041423924542">የዕውቅና ማረጋገጫን መምረጥ አልተቻለም።</translation> <translation id="8087000398470557479">ይህ ይዘት ከ<ph name="DOMAIN_NAME" /> የመጣ ነው፣ የተላከው በGoogle ነው።</translation> <translation id="8116925261070264013">ድምፀ ከል ተደርጓል</translation> <translation id="8131740175452115882">አረጋግጥ</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">አንድ ጣቢያ የእርስዎን ካሜራ እና ማይክሮፎን እየተጠቀመ ነው</translation> <translation id="8380167699614421159">ይህ ጣቢያ ረባሽ ወይም አሳሳች ማስታወቂያዎችን ያሳያል</translation> <translation id="8394832520002899662">ወደ ጣቢያው ለመመለስ መታ ያድርጉ</translation> +<translation id="8425213833346101688">ለውጥ</translation> +<translation id="8441146129660941386">ወደኋላ ፈልግ</translation> <translation id="8447861592752582886">የመሣሪያ ፈቃድ ሻር</translation> <translation id="8463851957836045671">ጣቢያ ፈጣን ነው</translation> <translation id="851751545965956758">ጣቢያዎች ከመሣሪያዎች ጋር እንዳይገናኙ አግድ</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">የአንድ የተወሰነ ጣቢያ ኩኪዎችን ያግዱ።</translation> <translation id="8959122750345127698">ዳሰሳ ሊደረስበት አይችልም፦ <ph name="URL" /></translation> <translation id="9019902583201351841">በእርስዎ ወላጆች የሚቀናበር</translation> +<translation id="9074739597929991885">ብሉቱዝ</translation> <translation id="945632385593298557">የእርስዎን ማይክሮፎን ይድረሱ</translation> <translation id="965817943346481315">ጣቢያው ረባሽ ወይም አሳሳች ማስታወቂያዎችን የሚያሳይ ከሆነ ማገድ (የሚመከር)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ar.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ar.xtb index 8f92b64fe96..d930585f828 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ar.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ar.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">التالي</translation> <translation id="1242008676835033345">مضمّن في <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">إيقاف</translation> +<translation id="1289742167380433257">لحفظ بياناتك، حسَّنت Google الصور في هذه الصفحة.</translation> <translation id="129382876167171263">تظهر هنا الملفات التي تحفظها المواقع الإلكترونية</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> - <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">تمت إضافة الموقع <ph name="SITE_NAME" /></translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">طلب الإذن قبل السماح لموقع إلكتروني بإنشاء خريطة ثلاثية الأبعاد للبيئة المحيطة بك أو تتبُّع موضع الكاميرا (مقترَح)</translation> <translation id="2212565012507486665">السماح بملفات تعريف الارتباط</translation> <translation id="2289270750774289114">طلب الإذن عند محاولة موقع إلكتروني العثور على أجهزة البلوتوث المجاورة (إجراء موصَى به)</translation> +<translation id="2315043854645842844">لا يدعم نظام التشغيل تحديد الشهادة من جانب العميل.</translation> <translation id="2359808026110333948">متابعة</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> ميغابايت</translation> <translation id="2434158240863470628">اكتمل التنزيل <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">تم النسخ</translation> <translation id="2822354292072154809">هل تريد فعلاً إعادة ضبط جميع أذونات الموقع الإلكتروني للكائن <ph name="CHOSEN_OBJECT_NAME" />؟</translation> <translation id="2870560284913253234">الموقع</translation> +<translation id="2874939134665556319">المقطع الصوتي السابق</translation> <translation id="2910701580606108292">السؤال قبل السماح للمواقع الإلكترونية بتشغيل المحتوى المحمي</translation> <translation id="2913331724188855103">السماح للمواقع الإلكترونية بحفظ بيانات ملفات تعريف الارتباط وقراءتها (موصى به)</translation> <translation id="2968755619301702150">عارض الشهادات</translation> <translation id="300526633675317032">سيؤدي هذا إلى محو مساحة التخزين البالغة <ph name="SIZE_IN_KB" /> بأكملها من مساحة تخزين المواقع الإلكترونية.</translation> +<translation id="301521992641321250">تم الحظر تلقائيًا</translation> <translation id="3115898365077584848">عرض المعلومات</translation> <translation id="3123473560110926937">حظر الإعلانات في بعض المواقع</translation> <translation id="3190152372525844641">تفعيل الأذونات لـ Chrome في <ph name="BEGIN_LINK" />إعدادات Android<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">المزامنة في الخلفية</translation> <translation id="3822502789641063741">هل تريد محو مساحة تخزين المواقع؟</translation> <translation id="385051799172605136">رجوع</translation> +<translation id="3859306556332390985">الانتقال للأمام</translation> <translation id="3955193568934677022">السماح للمواقع الإلكترونية بتشغيل المحتوى المحمي (مُستحسَن)</translation> <translation id="3987993985790029246">نسخ الرابط</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">العنوان</translation> <translation id="4008040567710660924">السماح لموقع إلكتروني معيّن بتشغيل ملفات تعريف الارتباط</translation> +<translation id="4046123991198612571">المقطع الصوتي التالي</translation> <translation id="4165986682804962316">إعدادات المواقع الإلكترونية</translation> <translation id="4226663524361240545">يمكن أن تؤدي الإشعارات إلى اهتزاز الجهاز</translation> <translation id="4242533952199664413">فتح الإعدادات</translation> <translation id="4259722352634471385">التنقل محظور: <ph name="URL" /></translation> <translation id="4278390842282768270">منح الإذن</translation> +<translation id="429312253194641664">تفعيل موقع إلكتروني للوسائط</translation> <translation id="4433925000917964731">نسخة خفيفة تقدِّمها Google</translation> <translation id="4434045419905280838">النوافذ المنبثقة وإعادة التوجيه</translation> <translation id="445467742685312942">السماح للمواقع الإلكترونية بتشغيل المحتوى المَحمي</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">إبطال جميع الأذونات للجهاز</translation> <translation id="4964199952259983386">للسماح لمتصفِّح Chrome باستخدام خدمة الواقع المعزّز (AR)، يُرجى أيضًا تفعيل الكاميرا في <ph name="BEGIN_LINK" />إعدادات Android<ph name="END_LINK" />.</translation> <translation id="497421865427891073">انتقال للأمام</translation> +<translation id="4996978546172906250">المشاركة عن طريق</translation> <translation id="5039804452771397117">سماح</translation> <translation id="5048398596102334565">السماح للمواقع الإلكترونية بالوصول إلى مستشعرات الحركة (مُقترَح)</translation> <translation id="5063480226653192405">الاستخدام</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">محو</translation> <translation id="6697925417670533197">عمليات التنزيل النشِطة</translation> <translation id="6746124502594467657">الانتقال إلى الأسفل</translation> +<translation id="6766622839693428701">يمكنك التمرير السريع للأسفل للإغلاق.</translation> <translation id="6782111308708962316">منع المواقع الإلكترونية التابعة لجهات خارجية من حفظ بيانات ملفات تعريف الارتباط وقراءتها</translation> +<translation id="6790428901817661496">التشغيل</translation> <translation id="6818926723028410516">اختيار عناصر</translation> <translation id="6864395892908308021">يتعذّر على هذا الجهاز قراءة NFC.</translation> <translation id="6910211073230771657">تم الحذف</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">هناك موقع إلكتروني يستخدم الكاميرا.</translation> <translation id="7817023149356982970">سيتم تسجيل خروجك من هذا الموقع الإلكتروني.</translation> <translation id="7828557259026017104">ملفات تعريف الارتباط هي ملفات تُنشئها المواقع الإلكترونية التي تزورها. وتستخدمها المواقع الإلكترونية لتتذكّر الإعدادات المفضّلة. أمّا ملفات تعريف الارتباط التابعة لجهات خارجية، فتُنشئها مواقع إلكترونية أخرى. وتمتلك هذه المواقع الإلكترونية بعضًا من المحتوى الذي تراه على صفحة الويب التي تزورها، مثل الإعلانات أو الصور.</translation> +<translation id="7835852323729233924">تشغيل الوسائط</translation> <translation id="7846076177841592234">إلغاء الاختيار</translation> <translation id="7846621471902887024">سيتم تسجيل خروجك من جميع المواقع الإلكترونية.</translation> <translation id="7882806643839505685">السماح بتشغيل الصوت لموقع معين.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">هل أنت متأكّد أنك تريد محو كل البيانات المحلية، بما في ذلك ملفات تعريف الارتباط، وإعادة ضبط كافة الأذونات لهذا الموقع الإلكتروني؟</translation> <translation id="8007176423574883786">تم إيقافه لهذا الجهاز</translation> <translation id="802154636333426148">تعذّر التنزيل</translation> +<translation id="8068648041423924542">يتعذر تحديد الشهادة.</translation> <translation id="8087000398470557479">هذا المحتوى من <ph name="DOMAIN_NAME" />، وتم عرضه من قبل Google.</translation> <translation id="8116925261070264013">المواقع الإلكترونية التي تم كتم الصوت فيها</translation> <translation id="8131740175452115882">التأكيد</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">هناك موقع إلكتروني يستخدم الميكروفون والكاميرا.</translation> <translation id="8380167699614421159">يعرض هذا الموقع الإلكتروني إعلانات مضلِّلة أو غير مرغوب فيها</translation> <translation id="8394832520002899662">يُرجى النقر للرجوع إلى الموقع الإلكتروني.</translation> +<translation id="8425213833346101688">تغيير</translation> +<translation id="8441146129660941386">الرجوع للوراء</translation> <translation id="8447861592752582886">إبطال إذن الجهاز</translation> <translation id="8463851957836045671">الموقع الإلكتروني سريع</translation> <translation id="851751545965956758">حظر المواقع الإلكترونية من الاتصال بأجهزة</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">حظر ملفات تعريف الارتباط لموقع إلكتروني مُحدَّد.</translation> <translation id="8959122750345127698">التنقل غير قابل للوصول: <ph name="URL" /></translation> <translation id="9019902583201351841">يديره والداك</translation> +<translation id="9074739597929991885">بلوتوث</translation> <translation id="945632385593298557">الدخول إلى الميكروفون</translation> <translation id="965817943346481315">الحظر في حال كان الموقع الإلكتروني يعرض إعلانات مضلِّلة أو غير مرغوب فيها (مُستحسَن)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_as.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_as.xtb index 54d7596299a..febece3ad44 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_as.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_as.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">পৰৱৰ্তী</translation> <translation id="1242008676835033345"><ph name="WEBSITE_URL" />ত এম্বেড কৰা হৈছে</translation> <translation id="1272079795634619415">বন্ধ কৰক</translation> +<translation id="1289742167380433257">আপোনাৰ ডেটা ৰাহি কৰিবলৈ Googleএ এই পৃষ্ঠাখনৰ প্ৰতিচ্ছবিসমূহ অপ্টিমাইজ কৰিছে।</translation> <translation id="129382876167171263">ৱেবছাইটে ছেভ কৰা ফাইলসমূহ ইয়াত দেখা পোৱা যায়</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> - <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">ছাইট <ph name="SITE_NAME" /> যোগ কৰা হ’ল</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">ছাইটসমূহক আপোনাৰ চৌপাশৰ এখন 3D মেপ সৃষ্টি কৰিবলৈ অথবা কেমেৰাৰ স্থান ট্ৰেক কৰিবলৈ অনুমতি দিয়াৰ পূর্বে সোধক (চুপাৰিছ কৰা হয়)</translation> <translation id="2212565012507486665">কুকিসমূহক অনুমতি দিয়ক</translation> <translation id="2289270750774289114">কোনো ছাইটে নিকটৱৰ্তী ডিভাইচ ব্লুটুথ ডিভাইচসমূহ পাব বিচাৰিলে সোধক (আমি চুপাৰিছ কৰোঁ)</translation> +<translation id="2315043854645842844">অপাৰেটিং ছিষ্টেমটোৱে ক্লায়েণ্টৰ ফালৰ প্ৰমাণপত্ৰ বাছনি কৰা সুবিধাটো সমৰ্থন নকৰে।</translation> <translation id="2359808026110333948">অব্যাহত ৰাখক</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> এম. বি.</translation> <translation id="2434158240863470628">ডাউনল’ড সম্পূর্ণ হৈছে <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">প্ৰতিলিপি কৰা হ'ল</translation> <translation id="2822354292072154809">আপুনি <ph name="CHOSEN_OBJECT_NAME" />ৰ বাবে ছাইটৰ সকলো অনুমতি ৰিছেট কৰিবলৈ বিচাৰে বুলি নিশ্চিতনে?</translation> <translation id="2870560284913253234">ছাইট</translation> +<translation id="2874939134665556319">পূৰ্বৱৰ্তী ট্ৰেক</translation> <translation id="2910701580606108292">ছাইটক প্রতিবন্ধিত সমল প্লে' কৰিব দিয়াৰ আগত সোধক</translation> <translation id="2913331724188855103">ছাইটসমূহক কুকি ডেটা ছেভ কৰিবলৈ আৰু পঢ়িবলৈ অনুমতি দিয়ক (আমি চুপাৰিছ কৰোঁ)</translation> <translation id="2968755619301702150">প্ৰমাণপত্ৰ ভিউৱাৰ</translation> <translation id="300526633675317032">এইটোৱে ৱেবছাইটৰ ষ্ট’ৰেজৰ সম্পূৰ্ণ <ph name="SIZE_IN_KB" /> মচি পেলাব।</translation> +<translation id="301521992641321250">স্বয়ংক্ৰিয়ভাৱে অৱৰোধ কৰা হৈছে</translation> <translation id="3115898365077584848">তথ্য দেখুৱাওক</translation> <translation id="3123473560110926937">কিছুমান ছাইটত অৱৰোধ কৰা আছে</translation> <translation id="3190152372525844641"><ph name="BEGIN_LINK" />Android ছেটিংসমূহ<ph name="END_LINK" />লৈ গৈ Chromeক অনুমতি প্ৰদান কৰক।</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">নেপথ্যত ছিংক কৰা</translation> <translation id="3822502789641063741">ছাইটৰ ষ্ট’ৰেজ মচিবনে?</translation> <translation id="385051799172605136">উভতি যাওক</translation> +<translation id="3859306556332390985">আগলৈ যাওক</translation> <translation id="3955193568934677022">ছাইটসমূহক সুৰক্ষিত সমল প্লে’ কৰিবলৈ অনুমতি দিয়ক (চুপাৰিছ কৰা হয়)</translation> <translation id="3987993985790029246">লিংক প্ৰতিলিপি কৰক</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">শিৰোনাম</translation> <translation id="4008040567710660924">কোনো নিৰ্দিষ্ট ছাইটৰ বাবে কুকিসমূহক অনুমতি দিয়ক।</translation> +<translation id="4046123991198612571">পৰৱৰ্তী ট্ৰেক</translation> <translation id="4165986682804962316">ছাইটৰ ছেটিংসমূহ</translation> <translation id="4226663524361240545">জাননীয়ে ডিভাইচটো কম্পন কৰিব পাৰে</translation> <translation id="4242533952199664413">ছেটিংসমূহ খোলক</translation> <translation id="4259722352634471385">নেভিগে’শ্বন অৱৰোধ কৰা আছে: <ph name="URL" /></translation> <translation id="4278390842282768270">অনুমতি দিয়া হৈছে</translation> +<translation id="429312253194641664">ছাইটটোৱে মিডিয়া প্লে’ কৰি আছে</translation> <translation id="4433925000917964731">Googleএ প্ৰদান কৰা লাইট পৃষ্ঠা</translation> <translation id="4434045419905280838">পপ-আপ আৰু পুনৰ নির্দেশ</translation> <translation id="445467742685312942">ছাইটসমূহক সুৰক্ষিত সমল প্লে' কৰিবলৈ অনুমতি দিয়ক</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">ডিভাইচৰ বাবে সকলো অনুমতি প্ৰত্যাহাৰ কৰক</translation> <translation id="4964199952259983386">Chromeক AR ব্যৱহাৰ কৰিবলৈ দিবলৈ <ph name="BEGIN_LINK" />Android ছেটিংসমূহ<ph name="END_LINK" />ত কেমেৰাও অন কৰক।</translation> <translation id="497421865427891073">আগুৱাই যাওক</translation> +<translation id="4996978546172906250">ইয়াৰ জৰিয়তে শ্বেয়াৰ কৰক</translation> <translation id="5039804452771397117">অনুমতি দিয়ক</translation> <translation id="5048398596102334565">ম'শ্বন ছেন্সৰসমূহলৈ এক্সেছ পাবলৈ ছাইটসমূহক অনুমতি দিয়ক (চুপাৰিছ কৰা)</translation> <translation id="5063480226653192405">ব্যৱহাৰ</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">মচক</translation> <translation id="6697925417670533197">সক্রিয় ডাউনল’ডসমূহ</translation> <translation id="6746124502594467657">তললৈ নিয়ক</translation> +<translation id="6766622839693428701">বন্ধ কৰিবলৈ তললৈ ছোৱাইপ কৰক।</translation> <translation id="6782111308708962316">তৃতীয় পক্ষৰ ৱেবছাইটসমূহে কুকি ডেটা ছেভ কৰা আৰু পঢ়াত বাধা দিয়ক</translation> +<translation id="6790428901817661496">প্লে’ কৰক</translation> <translation id="6818926723028410516">বস্তু বাছনি কৰক</translation> <translation id="6864395892908308021">এই ডিভাইচটোৱে NFC পঢ়িব নোৱাৰে</translation> <translation id="6910211073230771657">মচা হ’ল</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">এটা ছাইটে আপোনাৰ কেমেৰা ব্যৱহাৰ কৰি আছে</translation> <translation id="7817023149356982970">আপোনাক এই ছাইটটোৰ পৰা ছাইন আউট কৰোৱা হ’ব।</translation> <translation id="7828557259026017104">কুকিবোৰ হৈছে আপুনি চোৱা ৱেবছাইটসমূহে সৃষ্টি কৰা ফাইল। ছাইটসমূহে আপোনাৰ অগ্ৰাধিকাৰসমূহ মনত ৰাখিবলৈ সেইবোৰ ব্যৱহাৰ কৰে। তৃতীয় পক্ষৰ কুকিসমূহ অন্য ছাইটসমূহে সৃষ্টি কৰে। এই ছাইটসমূহ আপুনি চোৱা ৱেবছাইটটোত দেখা পোৱা বিজ্ঞাপন অথবা প্ৰতিচ্ছবিবোৰৰ দৰে কিছুমান সমলৰ গৰাকী।</translation> +<translation id="7835852323729233924">মিডিয়া প্লে’ হৈ আছে</translation> <translation id="7846076177841592234">বাছনি বাতিল কৰক</translation> <translation id="7846621471902887024">আপোনাক সকলো ছাইটৰ পৰা ছাইন আউট কৰোৱা হ’ব।</translation> <translation id="7882806643839505685">নির্দিষ্ট ছাইটৰ বাবে ধ্বনিৰ অনুমতি দিয়ক।</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">আপুনি এই ৱেবছাইটটোৰ কুকিকে ধৰি সকলো স্থানীয় ডেটা মচিব আৰু সকলো অনুমতি ৰিছেট কৰিব বিচাৰে বুলি নিশ্চিতনে?</translation> <translation id="8007176423574883786">এই ডিভাইচটোৰ বাবে অফ কৰা হৈছে</translation> <translation id="802154636333426148">ডাউনল’ড কৰিব পৰা নগ’ল</translation> +<translation id="8068648041423924542">প্ৰমাণপত্ৰ বাছনি কৰিব পৰা নগ'ল।</translation> <translation id="8087000398470557479">এই সমল Googleএ যোগান ধৰা <ph name="DOMAIN_NAME" />ৰ।</translation> <translation id="8116925261070264013">মিউট আছে</translation> <translation id="8131740175452115882">নিশ্চিত কৰক</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">এটা ছাইটে আপোনাৰ কেমেৰা আৰু মাইক্ৰ’ফ’ন ব্যৱহাৰ কৰি আছে</translation> <translation id="8380167699614421159">এই ছাইটটোৱে বিনা অনুমতিত বা কোনো বিভ্ৰান্তিকৰ বিজ্ঞাপন দেখুৱায়</translation> <translation id="8394832520002899662">এই ছাইটটোলৈ উভতি যাবলৈ টিপক</translation> +<translation id="8425213833346101688">সলনি কৰক</translation> +<translation id="8441146129660941386">পিছলৈ ছীক কৰক</translation> <translation id="8447861592752582886">ডিভাইচৰ অনুমতি প্ৰত্যাহাৰ কৰক</translation> <translation id="8463851957836045671">ছাইটটো দ্ৰুত</translation> <translation id="851751545965956758">ডিভাইচৰ সৈতে সংযোগ কৰাৰ পৰা ছাইটসমূহক অৱৰোধ কৰক</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">কোনো বিশেষ ছাইটৰ বাবে কুকিসমূহ অৱৰোধ কৰক।</translation> <translation id="8959122750345127698">ইয়ালৈ নেভিগেশ্বন পাব পৰা অৱস্থাত নাই: <ph name="URL" /></translation> <translation id="9019902583201351841">আপোনাৰ অভিভাৱকৰ দ্বাৰা পৰিচালিত</translation> +<translation id="9074739597929991885">ব্লুটুথ</translation> <translation id="945632385593298557">আপোনাৰ মাইক্ৰ'ফ'ন এক্সেছ কৰক</translation> <translation id="965817943346481315">কোনো ছাইটে অননুমোদিত বা বিভ্ৰান্তিকৰ বিজ্ঞাপন দেখুৱালে সেয়া অৱৰোধ কৰক ( চুপাৰিছ কৰা)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_az.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_az.xtb index 2df2b230b58..026fc13eceb 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_az.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_az.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Növbəti</translation> <translation id="1242008676835033345"><ph name="WEBSITE_URL" /> daxilində yerləşdirilib</translation> <translation id="1272079795634619415">Dayandırın</translation> +<translation id="1289742167380433257">Datanızı yadda saxlamaq üçün bu səhifənin şəkilləri Google tərəfindən optimallaşdırılıb.</translation> <translation id="129382876167171263">Veb saytların yadda saxladığı fayllar burada görünür</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> - <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676"><ph name="SITE_NAME" /> saytı əlavə edildi</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Saytların ətrafınızdakı sahələrin 3D xəritəsini yaratmasına və ya kamera mövqeyini izləməsinə icazə verməzdən əvvəl icazə tələb edin (tövsiyə edilir)</translation> <translation id="2212565012507486665">Kukilərə icazə verin</translation> <translation id="2289270750774289114">Sayt yaxınlıqdakı Bluetooth cihazlarını kəşf etmək istədikdə soruşun (tövsiyə edilir)</translation> +<translation id="2315043854645842844">Müştəri sayt sertifikatı seçimi əməliyyat sistemi tərəfindən dəstəklənmir.</translation> <translation id="2359808026110333948">Davam edin</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">Endirmə tamamlandı <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Kopyalandı</translation> <translation id="2822354292072154809"><ph name="CHOSEN_OBJECT_NAME" /> üçün bütün sayt icazələrini sıfırlamaq istədiyinizə əminsiniz?</translation> <translation id="2870560284913253234">Sayt</translation> +<translation id="2874939134665556319">Öncəki trek</translation> <translation id="2910701580606108292">Saytlar qorunan kontenti göstərmədən öncə icazə tələb edilsin</translation> <translation id="2913331724188855103">Saytlara kuki datanı saxlamağa və oxumağa imkan verir (tövsiyə olunur)</translation> <translation id="2968755619301702150">Sertifikat izləyici</translation> <translation id="300526633675317032">Bu, veb sayt yaddaşının <ph name="SIZE_IN_KB" /> hissəsini siləcək</translation> +<translation id="301521992641321250">Avtomatik olaraq blok edildi</translation> <translation id="3115898365077584848">Məlumatı göstərin</translation> <translation id="3123473560110926937">Bəzi saytlarda bloklandı</translation> <translation id="3190152372525844641">Chrome üçün icazələrin yandırmaq <ph name="BEGIN_LINK" /> Android Settings <ph name="END_LINK" /> .</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Arxa fon sinx</translation> <translation id="3822502789641063741">Sayt yaddaşı silinsin?</translation> <translation id="385051799172605136">Geri</translation> +<translation id="3859306556332390985">İrəli axtarın</translation> <translation id="3955193568934677022">Saytlara qorunan datanı oxumağa icazə verin (tövsiyə olunur)</translation> <translation id="3987993985790029246">Linki kopyalayın</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">Başlıq</translation> <translation id="4008040567710660924">Xüsusi sayt üçün kukilərə icazə verin.</translation> +<translation id="4046123991198612571">Növbəti trek</translation> <translation id="4165986682804962316">Sayt ayarları</translation> <translation id="4226663524361240545">Bildirişlər cihazı titrədə bilər</translation> <translation id="4242533952199664413">Ayarları açın</translation> <translation id="4259722352634471385">Naviqasiya bloklandı: <ph name="URL" /></translation> <translation id="4278390842282768270">İcazə verilib</translation> +<translation id="429312253194641664">Sayt media oxudur</translation> <translation id="4433925000917964731">Google'un dəstəklədiyi lite səhifəsi</translation> <translation id="4434045419905280838">Popap və yönləndirmələr</translation> <translation id="445467742685312942">Saytlara qorunan kontenti oxutmağa icazə verin</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Cihaz üçün bütün icazələri ləğv edin</translation> <translation id="4964199952259983386">Chrome'un artırılmış reallıqdan istifadə etməsi üçün <ph name="BEGIN_LINK" />Android Ayarlarında<ph name="END_LINK" /> kameranı da aktiv edin.</translation> <translation id="497421865427891073">İrəli</translation> +<translation id="4996978546172906250">Paylaşma vasitəsi:</translation> <translation id="5039804452771397117">İcazə verin</translation> <translation id="5048398596102334565">Saytların hərəkət sensorlarınıza daxil olmasına icazə verin (tövsiyə edilir)</translation> <translation id="5063480226653192405">Istifadə</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Silin</translation> <translation id="6697925417670533197">Aktiv endirmələr</translation> <translation id="6746124502594467657">Aşağı köçürün</translation> +<translation id="6766622839693428701">Bağlamaq üçün aşağı sürüşdürün.</translation> <translation id="6782111308708962316">Üçüncü tərəf veb saytları tərəfindən kuki datasının yadda saxlanılması və oxunmasının qarşısını alın</translation> +<translation id="6790428901817661496">Oxudun</translation> <translation id="6818926723028410516">Element seçin</translation> <translation id="6864395892908308021">Bu cihazda NFC dəstəklənmir</translation> <translation id="6910211073230771657">Silinib</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Sayt kameranızdan istifadə edir</translation> <translation id="7817023149356982970">Bu saytdan çıxacaqsınız.</translation> <translation id="7828557259026017104">Kukilər daxil olduğunuz veb saytların yaratdığı fayllardır. Saytlar tərcihlərinizi yadda saxlamaq üçün onlardan istifadə edir. Üçüncü tərəf kukiləri başqa saytlar tərəfindən yaradılır. Bu saytlar daxil olduğunuz veb səhifədə gördüyünüz reklam və ya şəkillər kimi bəzi məzmunların sahibidir.</translation> +<translation id="7835852323729233924">Medianın oxudulması</translation> <translation id="7846076177841592234">Seçimi ləğv edin</translation> <translation id="7846621471902887024">Bütün saytlardan çıxacaqsınız.</translation> <translation id="7882806643839505685">Xüsusi sayt üçün səsə icazə verin.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Bütün lokal datanı silmək və bu sayt üçün bütün icazələri sıfırlamaq istəyirsiniz?</translation> <translation id="8007176423574883786">Bu cihaz üçün söndürüldükdə</translation> <translation id="802154636333426148">Endirmə alınmadı</translation> +<translation id="8068648041423924542">Sertifikatı seçmək mümkün deyil.</translation> <translation id="8087000398470557479">Bu məzmun <ph name="DOMAIN_NAME" /> domenindəndir, Google tərəfindən çatdırılıb.</translation> <translation id="8116925261070264013">Səssiz</translation> <translation id="8131740175452115882">Təsdiq edin</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Sayt kamera və mikrofonunuzdan istifadə edir</translation> <translation id="8380167699614421159">Bu sayt inadçı və ya aldadıcı reklamlar göstərir</translation> <translation id="8394832520002899662">Sayta qayıtmaq üçün toxunun</translation> +<translation id="8425213833346101688">Dəyişin</translation> +<translation id="8441146129660941386">Geri axtarı</translation> <translation id="8447861592752582886">Cihaz icazəsini ləğv edin</translation> <translation id="8463851957836045671">Sayt sürətlidir</translation> <translation id="851751545965956758">Saytların cihazlara qoşulmasını blok edin</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Xüsusi sayt üçün kukiləri blok edin.</translation> <translation id="8959122750345127698">Naviqasiya əlçatmazdır: <ph name="URL" /></translation> <translation id="9019902583201351841">Valideynləriniz tərəfindən idarə olunur</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Mikrofonunuza giriş</translation> <translation id="965817943346481315">Sayt inadçı və ya aldadıcı reklamlar göstərirsə, blok edin (tövsiyə olunur)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_be.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_be.xtb index 3e03d353ff7..3ff039933cd 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_be.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_be.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Далей</translation> <translation id="1242008676835033345">Убудавана на сайце <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Спыніць</translation> +<translation id="1289742167380433257">Відарысы на гэтай старонцы былі аптымізаваны з дапамогай Google для эканоміі трафіка.</translation> <translation id="129382876167171263">Тут паказваюцца файлы, захаваныя вэб-сайтамі</translation> <translation id="1364532808393826295"><ph name="APP_NAME" />. <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Сайт <ph name="SITE_NAME" /> дададзены</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Пытацца, перш чым дазволіць сайтам ствараць 3D-карту вашага асяроддзя і адсочваць становішча камеры (рэкамендуецца)</translation> <translation id="2212565012507486665">Дазволіць файлы cookie</translation> <translation id="2289270750774289114">Пытацца, калі сайт спрабуе выявіць прылады Bluetooth паблізу (рэкамендуецца)</translation> +<translation id="2315043854645842844">Аперацыйная сістэма не падтрымлівае выбар сертыфіката кліента.</translation> <translation id="2359808026110333948">Працягнуць</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> МБ</translation> <translation id="2434158240863470628">Спампоўванне завершана <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Скапіравана</translation> <translation id="2822354292072154809">Сапраўды скінуць усе дазволы сайта для <ph name="CHOSEN_OBJECT_NAME" />?</translation> <translation id="2870560284913253234">Сайт</translation> +<translation id="2874939134665556319">Папярэдні трэк</translation> <translation id="2910701580606108292">Пытаць, перш чым дазволіць прайграванне абароненага змесціва на сайтах</translation> <translation id="2913331724188855103">Дазволіць сайтам захоўваць і чытаць даныя файлаў cookie (рэкамендуецца)</translation> <translation id="2968755619301702150">Звесткі пра сертыфікат</translation> <translation id="300526633675317032">Гэта вызваліць <ph name="SIZE_IN_KB" /> у сховішчы вэб-сайтаў.</translation> +<translation id="301521992641321250">Заблакіравана аўтаматычна</translation> <translation id="3115898365077584848">Паказаць інфармацыю</translation> <translation id="3123473560110926937">Заблакіравана на некаторых сайтах</translation> <translation id="3190152372525844641">Уключыце дазволы для Chrome у <ph name="BEGIN_LINK" />Наладах Android<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Фонавая сінхранізацыя</translation> <translation id="3822502789641063741">Ачысц. сховішча сайтаў?</translation> <translation id="385051799172605136">Назад</translation> +<translation id="3859306556332390985">Перайсці ўперад</translation> <translation id="3955193568934677022">Дазволіць сайтам прайграваць абароненае змесціва (рэкамендуецца)</translation> <translation id="3987993985790029246">Скапіраваць спасылку</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">Назва</translation> <translation id="4008040567710660924">Дазвол выкарыстання файлаў cookie ад канкрэтнага сайта.</translation> +<translation id="4046123991198612571">Наступны трэк</translation> <translation id="4165986682804962316">Налады сайта</translation> <translation id="4226663524361240545">Апавяшчэнні могуць уключаць вібрацыю прылады</translation> <translation id="4242533952199664413">Адкрыць налады</translation> <translation id="4259722352634471385">Пераход па наступным адрасе заблакіраваны: <ph name="URL" /></translation> <translation id="4278390842282768270">Дазволена</translation> +<translation id="429312253194641664">Сайт прайграе мультымедыя</translation> <translation id="4433925000917964731">Старонка, спрошчаная алгарытмамі Google</translation> <translation id="4434045419905280838">Усплыв. вокны і перанакіраванні</translation> <translation id="445467742685312942">Дазволіць сайтам прайграваць абароненае змесціва</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Адклікаць усе дазволы для прылады</translation> <translation id="4964199952259983386">Каб Chrome мог выкарыстоўваць дапоўненую рэальнасць, уключыце таксама камеру ў <ph name="BEGIN_LINK" />Наладах Android<ph name="END_LINK" />.</translation> <translation id="497421865427891073">Наперад</translation> +<translation id="4996978546172906250">Абагуліць праз</translation> <translation id="5039804452771397117">Дазволіць</translation> <translation id="5048398596102334565">Дазваляць сайтам доступ да датчыкаў руху (рэкамендуецца)</translation> <translation id="5063480226653192405">Выкарыстанне</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Ачысціць</translation> <translation id="6697925417670533197">Актыўныя спампоўкі</translation> <translation id="6746124502594467657">Перамясціць ніжэй</translation> +<translation id="6766622839693428701">Правядзіце пальцам уніз, каб закрыць.</translation> <translation id="6782111308708962316">Не даваць староннім вэб-сайтам захоўваць і чытаць даныя файлаў cookie</translation> +<translation id="6790428901817661496">Прайграць</translation> <translation id="6818926723028410516">Выберыце элементы</translation> <translation id="6864395892908308021">Гэта прылада не падтрымлівае функцыю NFC</translation> <translation id="6910211073230771657">Выдалена</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Сайт выкарыстоўвае камеру</translation> <translation id="7817023149356982970">Будзе выкананы выхад з гэтага сайта.</translation> <translation id="7828557259026017104">Файлы cookie – гэта файлы, якія ствараюцца наведанымі вамі вэб-сайтамі, каб запамінаць вашы налады. Староннія файлы cookie ствараюцца іншымі сайтамі. Гэтым сайтам належыць пэўнае змесціва (напрыклад рэклама або відарысы), размешчанае на вэб-старонцы, якую вы наведваеце.</translation> +<translation id="7835852323729233924">Прайграванне мультымедыя</translation> <translation id="7846076177841592234">Скасаваць выбар</translation> <translation id="7846621471902887024">Будзе выкананы выхад з усіх сайтаў.</translation> <translation id="7882806643839505685">Дазвол гуку на канкрэтным сайце.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Вы сапраўды хочаце ачысціць усе лакальныя даныя, у тым ліку файлы cookie, і скінуць усе дазволы для гэтага вэб-сайта?</translation> <translation id="8007176423574883786">Выключана для гэтай прылады</translation> <translation id="802154636333426148">Збой спампоўкі</translation> +<translation id="8068648041423924542">Не ўдаецца выбраць сертыфікат.</translation> <translation id="8087000398470557479">Змесціва з <ph name="DOMAIN_NAME" />, пастаўшчык – Google.</translation> <translation id="8116925261070264013">Без гуку</translation> <translation id="8131740175452115882">Пацвердзіць</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Сайт выкарыстоўвае камеру і мікрафон</translation> <translation id="8380167699614421159">Гэты сайт паказвае назойлівую рэкламу або рэкламу, якая ўводзіць у зман</translation> <translation id="8394832520002899662">Каб вярнуцца на сайт, націсніце тут</translation> +<translation id="8425213833346101688">Змяніць</translation> +<translation id="8441146129660941386">Перайсці назад</translation> <translation id="8447861592752582886">Адклікаць дазвол на доступ да прылады</translation> <translation id="8463851957836045671">Сайт хуткі</translation> <translation id="851751545965956758">Блакіраваць сайтам падключэнне да прылад</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Блакіраваць файлы cookie для пэўнага сайта.</translation> <translation id="8959122750345127698">Пераход па наступным адрасе недаступны: <ph name="URL" /></translation> <translation id="9019902583201351841">Пад кіраваннем вашых бацькоў</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Доступ да мікрафона</translation> <translation id="965817943346481315">Блакіраваць, калі сайт паказвае назойлівую рэкламу або рэкламу, якая ўводзіць у зман (рэкамендуецца)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_bg.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_bg.xtb index 5617ffb7c19..9e7ed388933 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_bg.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_bg.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Напред</translation> <translation id="1242008676835033345">Вграден в <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Стоп</translation> +<translation id="1289742167380433257">Изображенията на тази страница бяха оптимизирани от Google с цел пестене на данни.</translation> <translation id="129382876167171263">Тук се показват файловете, запазени от уебсайтове</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> – <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Сайтът <ph name="SITE_NAME" /> е добавен</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Извеждане на запитване, преди да се разреши на сайтовете да създават триизмерна карта на заобикалящата ви среда или да следят позицията на камерата (препоръчително)</translation> <translation id="2212565012507486665">Разрешаване на „бисквитките“</translation> <translation id="2289270750774289114">Извеждане на запитване, когато сайт иска да открива устройства с Bluetooth в близост (препоръчително)</translation> +<translation id="2315043854645842844">Избраният сертификат от страната на клиента не се поддържа от операционната система.</translation> <translation id="2359808026110333948">Напред</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> МБ</translation> <translation id="2434158240863470628">Изтеглянето завърши <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Копирано</translation> <translation id="2822354292072154809">Наистина ли искате да зададете повторно всички разрешения за сайта за <ph name="CHOSEN_OBJECT_NAME" />?</translation> <translation id="2870560284913253234">Сайт</translation> +<translation id="2874939134665556319">Предишен запис</translation> <translation id="2910701580606108292">Запитване преди разрешаване на сайтовете да възпроизвеждат защитено съдържание</translation> <translation id="2913331724188855103">Разрешаване на сайтовете да запазват „бисквитки“ и да четат данни от такива (препоръчително)</translation> <translation id="2968755619301702150">Визуализатор на сертификатите</translation> <translation id="300526633675317032">Така ще се изчистят всички съхранявани данни от уебсайтове (<ph name="SIZE_IN_KB" />).</translation> +<translation id="301521992641321250">Автоматично блокирано</translation> <translation id="3115898365077584848">Показване на информацията</translation> <translation id="3123473560110926937">Блокиране на някои сайтове</translation> <translation id="3190152372525844641">Включете разрешенията за Chrome от <ph name="BEGIN_LINK" />настройките на Android<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Синхронизиране на заден план</translation> <translation id="3822502789641063741">Изчистване на данните?</translation> <translation id="385051799172605136">Назад</translation> +<translation id="3859306556332390985">Придвижване напред</translation> <translation id="3955193568934677022">Разрешаване на сайтовете да възпроизвеждат защитено съдържание (препоръчително)</translation> <translation id="3987993985790029246">Връзка: Коп.</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> от ?</translation> <translation id="4002066346123236978">Заглавие</translation> <translation id="4008040567710660924">Разрешаване на „бисквитките“ за конкретен сайт.</translation> +<translation id="4046123991198612571">Следващ запис</translation> <translation id="4165986682804962316">Настройки за сайта</translation> <translation id="4226663524361240545">Възможно е устройството да вибрира при известия</translation> <translation id="4242533952199664413">Отваряне на настройките</translation> <translation id="4259722352634471385">Навигирането е блокирано: <ph name="URL" /></translation> <translation id="4278390842282768270">Разрешено</translation> +<translation id="429312253194641664">Сайт възпроизвежда мултимедийно съдържание</translation> <translation id="4433925000917964731">Олекотена страница, предоставена от Google</translation> <translation id="4434045419905280838">Изскач. прозорци и пренасочвания</translation> <translation id="445467742685312942">Разрешаване на сайтовете да възпроизвеждат защитено съдържание</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Отмяна на всички разрешения за устройството</translation> <translation id="4964199952259983386">За да разрешите на Chrome да използва AR, трябва да включите камерата от <ph name="BEGIN_LINK" />настройките на Android<ph name="END_LINK" />.</translation> <translation id="497421865427891073">Преминаване напред</translation> +<translation id="4996978546172906250">Споделяне чрез</translation> <translation id="5039804452771397117">Разрешаване</translation> <translation id="5048398596102334565">Разрешаване на достъпа на сайтовете до сензорите за движение (препоръчително)</translation> <translation id="5063480226653192405">Употреба</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Изчистване</translation> <translation id="6697925417670533197">Активни изтегляния</translation> <translation id="6746124502594467657">Придвижване надолу</translation> +<translation id="6766622839693428701">Прекарайте пръст надолу, за да затворите.</translation> <translation id="6782111308708962316">Забраняване на уебсайтовете на трети страни да запазват и четат данни в „бисквитки“</translation> +<translation id="6790428901817661496">Пускане</translation> <translation id="6818926723028410516">Избор на елементи</translation> <translation id="6864395892908308021">Това устройство не може да чете NFC</translation> <translation id="6910211073230771657">Изтрито</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Сайт използва камерата ви</translation> <translation id="7817023149356982970">Ще излезете от профила си в този сайт.</translation> <translation id="7828557259026017104">Това са файлове, създавани от уебсайтовете, които посещавате. Сайтовете ги използват, за да запомнят предпочитанията ви. „Бисквитките“ на трети страни се създават от други сайтове. Тези сайтове притежават част от съдържанието, като например реклами или изображения, което виждате на посетената от вас уеб страница.</translation> +<translation id="7835852323729233924">Възпроизвеждане на мултимедия</translation> <translation id="7846076177841592234">Анулиране на избора</translation> <translation id="7846621471902887024">Ще излезете от профила си във всички сайтове.</translation> <translation id="7882806643839505685">Разрешаване на звука за конкретен сайт.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Наистина ли искате да изчистите всички локални данни, включително „бисквитките“, и да нулирате всички разрешения за този уебсайт?</translation> <translation id="8007176423574883786">Изключено за това устройство</translation> <translation id="802154636333426148">Изтеглянето не бе успешно</translation> +<translation id="8068648041423924542">Сертификатът не може да бъде избран.</translation> <translation id="8087000398470557479">Това съдържание се показва от Google, а източникът му е <ph name="DOMAIN_NAME" />.</translation> <translation id="8116925261070264013">Заглушени</translation> <translation id="8131740175452115882">Потвърждаване</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Сайт използва камерата и микрофона ви</translation> <translation id="8380167699614421159">На този сайт се показват натрапчиви или подвеждащи реклами</translation> <translation id="8394832520002899662">Докоснете, за да се върнете към сайта</translation> +<translation id="8425213833346101688">Промяна</translation> +<translation id="8441146129660941386">Придвижване назад</translation> <translation id="8447861592752582886">Отмяна на разрешението за достъп до устройството</translation> <translation id="8463851957836045671">Сайтът е бърз</translation> <translation id="851751545965956758">Блокиране на сайтовете, така че да не се свързват с устройства</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Блокиране на „бисквитките“ за конкретен сайт.</translation> <translation id="8959122750345127698">Навигирането не е възможно: <ph name="URL" /></translation> <translation id="9019902583201351841">Управлява се от родителите ви</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Достъп до микрофона</translation> <translation id="965817943346481315">Блокиране, ако на сайта се показват натрапчиви или подвеждащи реклами (препоръчително)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_bn.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_bn.xtb index f5b37691a23..34e259b7e0e 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_bn.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_bn.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">পরের</translation> <translation id="1242008676835033345"><ph name="WEBSITE_URL" />-এ এম্বেড করা হয়েছে</translation> <translation id="1272079795634619415">বন্ধ</translation> +<translation id="1289742167380433257">আপনার ডেটা সেভ করার জন্য, এই পৃষ্ঠার ছবিগুলি Google অপ্টিমাইজ করেছে।</translation> <translation id="129382876167171263">ওয়েবসাইট যেসব ফাইল সেভ করে সেগুলি এখানে দেখা যায়</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> - <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676"><ph name="SITE_NAME" /> সাইট যোগ করা হয়েছে</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">আপনার আশেপাশের এলাকার একটি 3D ম্যাপ তৈরি করতে বা ক্যামেরার অবস্থান ট্র্যাক করতে কোনও সাইট অনুমোদন দেওয়ার আগে, একবার জিজ্ঞাসা করে নিন (সাজেস্ট করা হয়েছে)</translation> <translation id="2212565012507486665">কুকিগুলিকে অনুমতি দিন</translation> <translation id="2289270750774289114">কাছাকাছি ব্লুটুথ ডিভাইস আছে কিনা তা কোনও সাইট খুঁজতে চাইলে আমাকে জিজ্ঞাসা করুন (সাজেস্ট করা হচ্ছে)</translation> +<translation id="2315043854645842844">ক্লায়েন্ট সাইড সার্টিফিকেট নির্বাচন অপারেটিং সিসটেম দ্বারা সমর্থিত নয়।</translation> <translation id="2359808026110333948">চালিয়ে যান</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> এমবি</translation> <translation id="2434158240863470628"><ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /> ডাউনলোড সম্পূর্ণ হয়েছে</translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">প্রতিলিপি করা হয়েছে</translation> <translation id="2822354292072154809">আপনি কি <ph name="CHOSEN_OBJECT_NAME" />-এর জন্য সাইটের সব অনুমতি রিসেট করার ব্যাপারে নিশ্চিত?</translation> <translation id="2870560284913253234">সাইট</translation> +<translation id="2874939134665556319">পূর্ববর্তী ট্র্যাক</translation> <translation id="2910701580606108292">কোনও সাইটে সুরক্ষিত কন্টেন্ট চালু হওয়ার আগে আমায় জিজ্ঞেস করা হোক</translation> <translation id="2913331724188855103">সাইটগুলিকে কুকি ডেটা পড়ার এবং সংরক্ষণ করার অনুমতি দিন (প্রস্তাবিত)</translation> <translation id="2968755619301702150">সার্টিফিকেট প্রদর্শনকারী</translation> <translation id="300526633675317032">এটা ওয়েবসাইট স্টোরেজের <ph name="SIZE_IN_KB" />-এর পুরোটা সাফ করবে।</translation> +<translation id="301521992641321250">স্বয়ংক্রিয়ভাবে ব্লক করা হয়েছে</translation> <translation id="3115898365077584848">তথ্য দেখুন</translation> <translation id="3123473560110926937">কিছু সাইটে ব্লক করা হয়েছে</translation> <translation id="3190152372525844641"><ph name="BEGIN_LINK" />Android সেটিংসে<ph name="END_LINK" /> Chrome এর জন্য অনুমতিগুলি চালু করুন।</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">পটভূমি সিঙ্ক</translation> <translation id="3822502789641063741">সাইটের সঞ্চয়স্থান সাফ করবেন?</translation> <translation id="385051799172605136">ফিরুন</translation> +<translation id="3859306556332390985">সামনে এগোন</translation> <translation id="3955193568934677022">সুরক্ষিত কন্টেন্ট প্লে করতে সাইটগুলিকে মঞ্জুরি দিন (প্রস্তাবিত)</translation> <translation id="3987993985790029246">লিঙ্ক কপি করুন</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">শিরোনাম</translation> <translation id="4008040567710660924">কোনও নির্দিষ্ট সাইটের জন্য কুকিকে অনুমতি দিন।</translation> +<translation id="4046123991198612571">পরবর্তী ট্র্যাক</translation> <translation id="4165986682804962316">সাইটের সেটিংস</translation> <translation id="4226663524361240545">বিজ্ঞপ্তি আসলে ডিভাইস ভাইব্রেট হতে পারে</translation> <translation id="4242533952199664413">সেটিংস খুলুন</translation> <translation id="4259722352634471385">নেভিগেশন অবরুদ্ধ করা হয়েছে: <ph name="URL" /></translation> <translation id="4278390842282768270">মঞ্জুরিপ্রাপ্ত</translation> +<translation id="429312253194641664">একটি সাইট মিডিয়া চালাচ্ছে</translation> <translation id="4433925000917964731">Google লাইট পৃষ্ঠা পাঠিয়েছে</translation> <translation id="4434045419905280838">পপ-আপ এবং রিডাইরেক্ট</translation> <translation id="445467742685312942">সাইটকে সুরক্ষিত কন্টেন্ট চালানোর জন্য অনুমতি দিন</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">ডিভাইসের ক্ষেত্রে সমস্ত অনুমতি সরিয়ে দিন</translation> <translation id="4964199952259983386">এছাড়াও, Chrome-কে এ আর (AR) ব্যবহার করতে দিতে চাইলে, <ph name="BEGIN_LINK" />Android সেটিংস<ph name="END_LINK" /> থেকে ক্যামেরা চালু করতে হবে।</translation> <translation id="497421865427891073">অগ্রবর্তী করুন</translation> +<translation id="4996978546172906250">এর মাধ্যমে শেয়ার করুন</translation> <translation id="5039804452771397117">অনুমতি দিন</translation> <translation id="5048398596102334565">সাইটকে মোশন সেন্সর অ্যাক্সেস করার অনুমতি দিন (সাজেস্ট করা হয়)</translation> <translation id="5063480226653192405">ব্যবহার</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">সাফ করুন</translation> <translation id="6697925417670533197">ডাউনলোড করা হচ্ছে</translation> <translation id="6746124502594467657">নিচে যান</translation> +<translation id="6766622839693428701">বন্ধ করতে নিচের দিকে সোয়াইপ করুন।</translation> <translation id="6782111308708962316">কুকি ডেটা সংরক্ষণ করা এবং পড়া থেকে তৃতীয় পক্ষের ওয়েবসাইটগুলিকে আটকান</translation> +<translation id="6790428901817661496">চালু করুন</translation> <translation id="6818926723028410516">আইটেম বেছে নিন</translation> <translation id="6864395892908308021">এই ডিভাইস NFC পড়তে পারছে না</translation> <translation id="6910211073230771657">মোছা হয়েছে</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">একটি সাইট আপনার ক্যামেরা ব্যবহার করছে</translation> <translation id="7817023149356982970">আপনি এই সাইট থেকে সাইন-আউট হয়ে যাবেন।</translation> <translation id="7828557259026017104">আপনার ব্রাউজ করা ওয়েবসাইটের তৈরি করা ফাইলগুলিকে 'কুকি' বলা হয়। সাইট আপনার পছন্দগুলি মনে রাখতে, কুকি ব্যবহার করে। অন্যান্য সাইট 'থার্ড-পার্টি কুকি' তৈরি করে। এই সাইটগুলিতে বিজ্ঞাপন এবং ছবির মতো কিছু কন্টেন্ট থাকে, যেগুলি আপনার ভিজিট করা ওয়েবপেজে আপনি দেখতে পান।</translation> +<translation id="7835852323729233924">মিডিয়া চালানো হচ্ছে</translation> <translation id="7846076177841592234">নির্বাচন বাতিল করুন</translation> <translation id="7846621471902887024">আপনি সমস্ত সাইট থেকে সাইন-আউট হয়ে যাবেন।</translation> <translation id="7882806643839505685">একটি নির্দিষ্ট সাইটের জন্য সাউন্ড প্লে করার অনুমতি দিন।</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">আপনি কি এই ওয়েবসাইটের কুকি সহ সমস্ত ডেটা পরিষ্কার করার এবং এটির সমস্ত অনুমতি রিসেট করার বিষয়ে নিশ্চিত?</translation> <translation id="8007176423574883786">এই ডিভাইসের জন্য বন্ধ করা আছে</translation> <translation id="802154636333426148">ডাউনলোড করা যায়নি</translation> +<translation id="8068648041423924542">সার্টিফিকেট বেছে নিতে পারেনি।</translation> <translation id="8087000398470557479">এই কন্টেন্ট Google দ্বারা বিতরণ করা <ph name="DOMAIN_NAME" /> থেকে এসেছে।</translation> <translation id="8116925261070264013">মিউট করা আছে</translation> <translation id="8131740175452115882">নিশ্চিত হন</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">একটি সাইট আপনার ক্যামেরা ও মাইক্রোফোন ব্যবহার করছে</translation> <translation id="8380167699614421159">এই সাইট ব্যাঘাত সৃষ্টিকারী বা বিভ্রান্তিকর বিজ্ঞাপন দেখায়</translation> <translation id="8394832520002899662">সাইটে ফিরে যেতে ট্যাপ করুন</translation> +<translation id="8425213833346101688">পরিবর্তন</translation> +<translation id="8441146129660941386">পেছনে যান</translation> <translation id="8447861592752582886">ডিভাইসের অনুমতি প্রত্যাহার করুন</translation> <translation id="8463851957836045671">সাইট খুব দ্রুত লোড হয়</translation> <translation id="851751545965956758">সাইটকে ডিভাইসের সাথে কানেক্ট করা থেকে ব্লক করুন</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">কোনও নির্দিষ্ট সাইটের জন্য কুকি ব্লক করুন।</translation> <translation id="8959122750345127698">নেভিগেশানে পৌছানো যাচ্ছে না: <ph name="URL" /></translation> <translation id="9019902583201351841">আপনার পিতামাতার দ্বারা পরিচালিত</translation> +<translation id="9074739597929991885">ব্লুটুথ</translation> <translation id="945632385593298557">আপনার মাইক্রোফোন অ্যাক্সেস করুন</translation> <translation id="965817943346481315">সাইটে থাকা ব্যাঘাত সৃষ্টিকারী বা বিভ্রান্তিকর বিজ্ঞাপন ব্লক করুন (প্রস্তাবিত)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_bs.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_bs.xtb index 7a6eccbc8e4..bc05e78e3b4 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_bs.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_bs.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Naprijed</translation> <translation id="1242008676835033345">Ugrađeno na <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Zaustavi</translation> +<translation id="1289742167380433257">Da sačuvate podatke, Google je optimizirao slike ove stranice.</translation> <translation id="129382876167171263">Fajlovi koje sačuvaju web lokacije će se pojaviti ovdje</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> – <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Web lokacija <ph name="SITE_NAME" /> je dodana</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Web lokacije moraju tražiti odobrenje za kreiranje 3D mape okruženja i praćenje položaja kamere (preporučeno)</translation> <translation id="2212565012507486665">Dozvoli kolačiće</translation> <translation id="2289270750774289114">Pitaj kada web lokacija želi otkriti Bluetooth uređaje u blizini (preporučeno)</translation> +<translation id="2315043854645842844">Operativni sistem ne podržava odabir potvrde na strani klijenta.</translation> <translation id="2359808026110333948">Nastavi</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">Preuzimanje je završeno <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Kopirano</translation> <translation id="2822354292072154809">Jeste li sigurni da želite poništiti sva odobrenja web lokacije za <ph name="CHOSEN_OBJECT_NAME" />?</translation> <translation id="2870560284913253234">Web lokacija</translation> +<translation id="2874939134665556319">Prethodna numera</translation> <translation id="2910701580606108292">Web lokacije moraju tražiti dozvolu za reprodukciju zaštićenog sadržaja</translation> <translation id="2913331724188855103">Omogućite web lokacijama da sačuvaju i čitaju podatke o kolačićima (preporučeno)</translation> <translation id="2968755619301702150">Preglednik certifikata</translation> <translation id="300526633675317032">Time će se izbrisati cijela pohrana web-lokacije veličine <ph name="SIZE_IN_KB" />.</translation> +<translation id="301521992641321250">Automatski blokirano</translation> <translation id="3115898365077584848">Prikaži informacije</translation> <translation id="3123473560110926937">Blokirano na nekim web lokacijama</translation> <translation id="3190152372525844641">Uključite odobrenja za Chrome u <ph name="BEGIN_LINK" />Postavkama Androida<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Sinhronizacija u pozadini</translation> <translation id="3822502789641063741">Obrisati pohranu?</translation> <translation id="385051799172605136">Nazad</translation> +<translation id="3859306556332390985">Pomakni naprijed</translation> <translation id="3955193568934677022">Dozvoljava web lokacijama da reproduciraju zaštićeni sadržaj (preporučeno)</translation> <translation id="3987993985790029246">Kopiraj link</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> <translation id="4002066346123236978">Naslov</translation> <translation id="4008040567710660924">Omogućavanje kolačića za određenu web lokaciju.</translation> +<translation id="4046123991198612571">Sljedeća pjesma</translation> <translation id="4165986682804962316">Postavke web-lokacije</translation> <translation id="4226663524361240545">Obavještenja mogu aktivirati vibraciju uređaja</translation> <translation id="4242533952199664413">Otvori postavke</translation> <translation id="4259722352634471385">Navigacija je blokirana: <ph name="URL" /></translation> <translation id="4278390842282768270">Dozvoljeno</translation> +<translation id="429312253194641664">Web lokacija reproducira medij</translation> <translation id="4433925000917964731">Jednostavnu stranicu omogućava Google</translation> <translation id="4434045419905280838">Skočni proz. i preusmjeravanja</translation> <translation id="445467742685312942">Dozvoljava web lokacijama da reproduciraju zaštićen sadržaj</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Opoziv svih dopuštenja za uređaj</translation> <translation id="4964199952259983386">Da Chromeu dozvolite korištenje AR-a, također uključite kameru u <ph name="BEGIN_LINK" />Postavkama Androida<ph name="END_LINK" />.</translation> <translation id="497421865427891073">Idi naprijed</translation> +<translation id="4996978546172906250">Dijeljenje koristeći</translation> <translation id="5039804452771397117">Dozvoli</translation> <translation id="5048398596102334565">Dozvoli web lokacijama pristup senzorima pokreta (preporučeno)</translation> <translation id="5063480226653192405">Korištenje</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Obriši</translation> <translation id="6697925417670533197">Aktivna preuzimanja</translation> <translation id="6746124502594467657">Pomjeri dolje</translation> +<translation id="6766622839693428701">Prevucite prema dolje da zatvorite.</translation> <translation id="6782111308708962316">Spriječi web lokacije treće strane da pohranjuju i čitaju podatke kolačića</translation> +<translation id="6790428901817661496">Pokreni</translation> <translation id="6818926723028410516">Odaberite stavke</translation> <translation id="6864395892908308021">Ovaj uređaj ne može očitavati NFC</translation> <translation id="6910211073230771657">Izbrisano</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Web lokacija koristi vašu kameru</translation> <translation id="7817023149356982970">Odjavit ćete se s ove web lokacije.</translation> <translation id="7828557259026017104">Kolačići su fajlovi koje kreiraju web lokacije koje posjetite. Web lokacije ih koriste da zapamte vaše preference. Kolačiće treće strane kreiraju druge web lokacije. Te web lokacije posjeduju dio sadržaja, kao što su oglasi ili slike, koji se prikazuje na web stranici koju posjećujete.</translation> +<translation id="7835852323729233924">Reproduciranje medija</translation> <translation id="7846076177841592234">Otkazivanje odabira</translation> <translation id="7846621471902887024">Odjavit ćete se sa svih web lokacija.</translation> <translation id="7882806643839505685">Omogućavanje zvuka za određenu web lokaciju.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Jeste li sigurni da želite obrisati sve lokalne podatke, uključujući kolačiće i poništiti sva odobrenja za ovu web lokaciju?</translation> <translation id="8007176423574883786">Isključeno za ovaj uređaj</translation> <translation id="802154636333426148">Preuzimanje nije uspjelo</translation> +<translation id="8068648041423924542">Nije moguće odabrati potvrdu.</translation> <translation id="8087000398470557479">Ovaj sadržaj je iz domene <ph name="DOMAIN_NAME" />, a isporučio ga je Google.</translation> <translation id="8116925261070264013">Isključen zvuk</translation> <translation id="8131740175452115882">Potvrdi</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Web lokacija koristi vašu kameru i mikrofon</translation> <translation id="8380167699614421159">Ova web lokacija prikazuje ometajuće ili obmanjujuće oglase</translation> <translation id="8394832520002899662">Dodirnite da se vratite na web lokaciju</translation> +<translation id="8425213833346101688">Izmijeni</translation> +<translation id="8441146129660941386">Pomicanje unazad</translation> <translation id="8447861592752582886">Opozivanje dozvole za uređaj</translation> <translation id="8463851957836045671">Web lokacija je brza</translation> <translation id="851751545965956758">Blokiraj povezivanje web-lokacija s uređajima</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Blokiranje kolačića za određenu web lokaciju.</translation> <translation id="8959122750345127698">Navigacija je nedostupna: <ph name="URL" /></translation> <translation id="9019902583201351841">Upravljaju tvoji roditelji</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Pristup mikrofonu</translation> <translation id="965817943346481315">Blokirajte ako web lokacija prikazuje nametljive ili obmanjujuće oglase (preporučeno)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ca.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ca.xtb index 60f52a6329f..a6a6ab9f147 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ca.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ca.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Següent</translation> <translation id="1242008676835033345">Incrustada a <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Atura</translation> +<translation id="1289742167380433257">Perquè estalviïs dades, Google ha optimitzat les imatges d'aquesta pàgina.</translation> <translation id="129382876167171263">Els fitxers desats pels llocs web es mostren aquí</translation> <translation id="1364532808393826295"><ph name="APP_NAME" />: <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">El lloc <ph name="SITE_NAME" /> s'ha afegit</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Pregunta abans de permetre que els llocs web creïn un mapa en 3D del teu entorn o facin un seguiment de la posició de la càmera (opció recomanada)</translation> <translation id="2212565012507486665">Permet les galetes</translation> <translation id="2289270750774289114">Pregunta'm quan un lloc web vulgui descobrir dispositius Bluetooth propers (opció recomanada)</translation> +<translation id="2315043854645842844">El sistema operatiu no permet seleccionar el certificat del client.</translation> <translation id="2359808026110333948">Continua</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">S'ha completat la baixada <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Copiada</translation> <translation id="2822354292072154809">Confirmes que vols restablir tots els permisos del lloc web concedits a <ph name="CHOSEN_OBJECT_NAME" />?</translation> <translation id="2870560284913253234">Lloc web</translation> +<translation id="2874939134665556319">Pista anterior</translation> <translation id="2910701580606108292">Pregunta abans de permetre que els llocs web reprodueixin contingut protegit</translation> <translation id="2913331724188855103">Permet que els llocs web desin i llegeixin les dades de les galetes (opció recomanada)</translation> <translation id="2968755619301702150">Lector de certificats</translation> <translation id="300526633675317032">Amb aquesta acció s'esborraran <ph name="SIZE_IN_KB" /> d'emmagatzematge del lloc web.</translation> +<translation id="301521992641321250">Bloquejada automàticament</translation> <translation id="3115898365077584848">Mostra la informació</translation> <translation id="3123473560110926937">Bloquejat en alguns llocs web</translation> <translation id="3190152372525844641">Activa els permisos per a Chrome a la <ph name="BEGIN_LINK" />configuració d'Android<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Sincronització en segon pla</translation> <translation id="3822502789641063741">Esborrem emmagatz. lloc web?</translation> <translation id="385051799172605136">Enrere</translation> +<translation id="3859306556332390985">Avança</translation> <translation id="3955193568934677022">Permet que els llocs web reprodueixin contingut protegit (opció recomanada)</translation> <translation id="3987993985790029246">Copia l'enllaç</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> <translation id="4002066346123236978">Títol</translation> <translation id="4008040567710660924">Permet les galetes d'un lloc web concret.</translation> +<translation id="4046123991198612571">Pista següent</translation> <translation id="4165986682804962316">Configuració del lloc web</translation> <translation id="4226663524361240545">És possible que les notificacions facin vibrar el dispositiu</translation> <translation id="4242533952199664413">Obre la configuració</translation> <translation id="4259722352634471385">S'ha bloquejat la navegació: <ph name="URL" /></translation> <translation id="4278390842282768270">Permès</translation> +<translation id="429312253194641664">Un lloc web està reproduint contingut multimèdia</translation> <translation id="4433925000917964731">Pàgina en mode bàsic oferida per Google</translation> <translation id="4434045419905280838">Finestres emergents i redireccions</translation> <translation id="445467742685312942">Permet que els llocs web reprodueixin contingut protegit</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Revoca tots els permisos del dispositiu</translation> <translation id="4964199952259983386">Per permetre que Chrome utilitzi RA, activa també la càmera a la <ph name="BEGIN_LINK" />configuració d'Android<ph name="END_LINK" />.</translation> <translation id="497421865427891073">Ves endavant</translation> +<translation id="4996978546172906250">Comparteix mitjançant</translation> <translation id="5039804452771397117">Permet</translation> <translation id="5048398596102334565">Permet que els llocs web accedeixin als sensors de moviment (opció recomanada)</translation> <translation id="5063480226653192405">Ús</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Esborra</translation> <translation id="6697925417670533197">Baixades actives</translation> <translation id="6746124502594467657">Mou avall</translation> +<translation id="6766622839693428701">Llisca cap avall per tancar el full.</translation> <translation id="6782111308708962316">Impedeix que els llocs web de tercers desin i llegeixin les dades de les galetes</translation> +<translation id="6790428901817661496">Reprodueix</translation> <translation id="6818926723028410516">Selecciona elements</translation> <translation id="6864395892908308021">Aquest dispositiu no pot llegir NFC</translation> <translation id="6910211073230771657">Suprimit</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Un lloc web està utilitzant la càmera</translation> <translation id="7817023149356982970">Se't tancarà la sessió d'aquest lloc web.</translation> <translation id="7828557259026017104">Les galetes són fitxers que creen els llocs web que visites. Els llocs web les fan servir per recordar les teves preferències. Les galetes de tercers són les que creen altres llocs web. Part del contingut d'aquests llocs, com ara els anuncis o les imatges, es mostra a la pàgina web que visites.</translation> +<translation id="7835852323729233924">Reproduint contingut multimèdia</translation> <translation id="7846076177841592234">Cancel·la la selecció</translation> <translation id="7846621471902887024">Se't tancarà la sessió de tots els llocs web.</translation> <translation id="7882806643839505685">Permet el so d'un lloc web concret.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Confirmes que vols esborrar d'aquest lloc web totes les dades locals, incloses les galetes, i restablir-ne tots els permisos?</translation> <translation id="8007176423574883786">Aquesta ubicació està desactivada per a aquest dispositiu</translation> <translation id="802154636333426148">Error de baixada</translation> +<translation id="8068648041423924542">No es pot seleccionar el certificat.</translation> <translation id="8087000398470557479">Aquest contingut és del domini <ph name="DOMAIN_NAME" />, oferit per Google.</translation> <translation id="8116925261070264013">Silenciats</translation> <translation id="8131740175452115882">Confirma</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Un lloc web està utilitzant la càmera i el micròfon</translation> <translation id="8380167699614421159">Aquest lloc web mostra anuncis intrusius o enganyosos</translation> <translation id="8394832520002899662">Toca per tornar al lloc web</translation> +<translation id="8425213833346101688">Canvia</translation> +<translation id="8441146129660941386">Retrocedeix</translation> <translation id="8447861592752582886">Revoca el permís d'accés al dispositiu</translation> <translation id="8463851957836045671">El lloc web és ràpid</translation> <translation id="851751545965956758">Impedeix que els llocs web es connectin a dispositius</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Bloqueja les galetes d'un lloc web concret.</translation> <translation id="8959122750345127698">No es pot accedir a la navegació: <ph name="URL" /></translation> <translation id="9019902583201351841">Gestionat pels pares</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Accés al micròfon</translation> <translation id="965817943346481315">Bloqueja els anuncis si el lloc web mostra publicitat intrusiva o enganyosa (opció recomanada)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_cs.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_cs.xtb index 44d4b5b7285..16850d2dce3 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_cs.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_cs.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Další</translation> <translation id="1242008676835033345">Vloženo do <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Zastavit</translation> +<translation id="1289742167380433257">Google obrázky na této stránce optimalizoval, abyste ušetřili data.</translation> <translation id="129382876167171263">Zde se budou zobrazovat soubory uložené webovými stránkami</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> – <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Byl přidán web <ph name="SITE_NAME" /></translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Předtím, než webům bude povoleno vytvořit 3D mapu vašeho okolí nebo sledovat polohu kamery, se zeptat (doporučeno)</translation> <translation id="2212565012507486665">Povolit cookies</translation> <translation id="2289270750774289114">Zeptat se, když chce web objevit zařízení Bluetooth v okolí (doporučeno)</translation> +<translation id="2315043854645842844">Volbu certifikátu na straně klienta operační systém nepodporuje.</translation> <translation id="2359808026110333948">Pokračovat</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">Stažení bylo dokončeno <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Zkopírováno</translation> <translation id="2822354292072154809">Opravdu chcete resetovat všechna oprávnění webů pro objekt <ph name="CHOSEN_OBJECT_NAME" />?</translation> <translation id="2870560284913253234">Stránky</translation> +<translation id="2874939134665556319">Předchozí skladba</translation> <translation id="2910701580606108292">Před povolením spuštění chráněného obsahu na webu se zeptat</translation> <translation id="2913331724188855103">Povolit webům ukládat a číst data souborů cookie (doporučeno)</translation> <translation id="2968755619301702150">Prohlížeč certifikátů</translation> <translation id="300526633675317032">Tímto vymažete celé úložiště webů (<ph name="SIZE_IN_KB" />).</translation> +<translation id="301521992641321250">Automaticky blokováno</translation> <translation id="3115898365077584848">Zobrazit informace</translation> <translation id="3123473560110926937">Na některých webech blokováno</translation> <translation id="3190152372525844641">Oprávnění pro Chrome zapnete v <ph name="BEGIN_LINK" />Nastavení pro Android<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Synchronizace na pozadí</translation> <translation id="3822502789641063741">Vymazat úložiště webů?</translation> <translation id="385051799172605136">Zpět</translation> +<translation id="3859306556332390985">Přetočit dopředu</translation> <translation id="3955193568934677022">Povolit webům přehrávat chráněný obsah (doporučeno)</translation> <translation id="3987993985790029246">Kopírovat odkaz</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">Název</translation> <translation id="4008040567710660924">Povolit soubory cookie pro konkrétní web.</translation> +<translation id="4046123991198612571">Další skladba</translation> <translation id="4165986682804962316">Nastavení webu</translation> <translation id="4226663524361240545">Oznámení mohou aktivovat vibraci</translation> <translation id="4242533952199664413">Otevřít Nastavení</translation> <translation id="4259722352634471385">Navigace je blokována: <ph name="URL" /></translation> <translation id="4278390842282768270">Povoleno</translation> +<translation id="429312253194641664">Web přehrává média</translation> <translation id="4433925000917964731">Zjednodušenou stránku poskytuje Google</translation> <translation id="4434045419905280838">Vyskakovací okna a přesměrování</translation> <translation id="445467742685312942">Povolit webům přehrávat chráněný obsah</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Zrušit všechna oprávnění pro zařízení</translation> <translation id="4964199952259983386">Chcete-li Chromu povolit používání rozšířené reality, zapněte v <ph name="BEGIN_LINK" />Nastavení Android<ph name="END_LINK" /> fotoaparát.</translation> <translation id="497421865427891073">Vpřed</translation> +<translation id="4996978546172906250">Sdílet prostřednictvím</translation> <translation id="5039804452771397117">Povolit</translation> <translation id="5048398596102334565">Povolit webům přístup k senzorům pohybu (doporučeno)</translation> <translation id="5063480226653192405">Použití</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Vymazat</translation> <translation id="6697925417670533197">Aktivní stahování</translation> <translation id="6746124502594467657">Posunout dolů</translation> +<translation id="6766622839693428701">Zavřete přejetím prstem dolů.</translation> <translation id="6782111308708962316">Zabránit webům třetích stran v ukládání a čtení dat souborů cookie</translation> +<translation id="6790428901817661496">Přehrát</translation> <translation id="6818926723028410516">Výběr položek</translation> <translation id="6864395892908308021">Toto zařízení neumí číst NFC</translation> <translation id="6910211073230771657">Smazáno</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Web používá váš fotoaparát</translation> <translation id="7817023149356982970">Budete odhlášeni z tohoto webu.</translation> <translation id="7828557259026017104">Soubory cookie jsou vytvářeny webovými stránkami, které navštěvujete. Weby je používají k tomu, aby si zapamatovaly vaše preference. Soubory cookie třetích stran jsou vytvářeny ostatními weby. Tyto weby na navštívené stránce vlastní nějaký obsah, např. reklamy nebo obrázky.</translation> +<translation id="7835852323729233924">Přehrávání médií</translation> <translation id="7846076177841592234">Zrušit výběr</translation> <translation id="7846621471902887024">Budete odhlášeni ze všech webů.</translation> <translation id="7882806643839505685">Zapne zvuk na konkrétním webu.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Opravdu chcete vymazat všechna místní data tohoto webu, včetně souborů cookie, a resetovat všechna jeho oprávnění?</translation> <translation id="8007176423574883786">Vypnuto v tomto zařízení</translation> <translation id="802154636333426148">Stažení se nezdařilo</translation> +<translation id="8068648041423924542">Certifikát nelze vybrat.</translation> <translation id="8087000398470557479">Tento obsah pochází z domény <ph name="DOMAIN_NAME" />. Poskytováno společností Google.</translation> <translation id="8116925261070264013">Ztlumeno</translation> <translation id="8131740175452115882">Potvrdit</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Webové stránky používají váš fotoaparát a mikrofon</translation> <translation id="8380167699614421159">Tento web zobrazuje rušivé nebo zavádějící reklamy</translation> <translation id="8394832520002899662">Klepnutím se vrátíte na web</translation> +<translation id="8425213833346101688">Změnit</translation> +<translation id="8441146129660941386">Přetočit dozadu</translation> <translation id="8447861592752582886">Zrušit oprávnění zařízení</translation> <translation id="8463851957836045671">Web je rychlý</translation> <translation id="851751545965956758">Bránit webům v připojení k zařízením</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Blokovat soubory cookie pro konkrétní web.</translation> <translation id="8959122750345127698">Navigace není dosažitelná: <ph name="URL" /></translation> <translation id="9019902583201351841">Spravováno vašimi rodiči</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Přístup k mikrofonu</translation> <translation id="965817943346481315">Blokovat, pokud web zobrazuje rušivé nebo zavádějící reklamy (doporučeno)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_da.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_da.xtb index d24448ee744..e7f799d8333 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_da.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_da.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Næste</translation> <translation id="1242008676835033345">Indlejret på <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Stop</translation> +<translation id="1289742167380433257">Billederne på denne side er blevet optimeret af Google, så du sparer data.</translation> <translation id="129382876167171263">Filer, der gemmes af websites, vises her</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> – <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Websitet <ph name="SITE_NAME" /> blev tilføjet</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Spørg, inden websites kan oprette et 3D-kort over dine omgivelser eller registrere kamerapositionen (anbefales)</translation> <translation id="2212565012507486665">Tillad cookies</translation> <translation id="2289270750774289114">Spørg, når et website vil søge efter Bluetooth-enheder i nærheden (anbefalet)</translation> +<translation id="2315043854645842844">Klientens certifikatvalg understøttes ikke af operativsystemet.</translation> <translation id="2359808026110333948">Fortsæt</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">Downloaden er fuldført <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Kopieret</translation> <translation id="2822354292072154809">Er du sikker på, at du vil nulstille alle websitetilladelser for <ph name="CHOSEN_OBJECT_NAME" />?</translation> <translation id="2870560284913253234">Website</translation> +<translation id="2874939134665556319">Forrige nummer</translation> <translation id="2910701580606108292">Spørg, før websites begynder at afspille beskyttet indhold</translation> <translation id="2913331724188855103">Tillad, at websites gemmer og læser cookiedata (anbefales)</translation> <translation id="2968755619301702150">Certifikatfremviser</translation> <translation id="300526633675317032">Dette rydder alle <ph name="SIZE_IN_KB" /> i websitelagerpladsen.</translation> +<translation id="301521992641321250">Automatisk blokering</translation> <translation id="3115898365077584848">Vis info</translation> <translation id="3123473560110926937">Blokeret på visse websites</translation> <translation id="3190152372525844641">Aktivér tilladelser for Chrome i <ph name="BEGIN_LINK" />Android-indstillingerne<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Synkronisering i baggrunden</translation> <translation id="3822502789641063741">Vil du rydde websitelagerpladsen?</translation> <translation id="385051799172605136">Tilbage</translation> +<translation id="3859306556332390985">Spol fremad</translation> <translation id="3955193568934677022">Tillad, at websites afspiller beskyttet indhold (anbefales)</translation> <translation id="3987993985790029246">Kopiér linket</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> <translation id="4002066346123236978">Titel</translation> <translation id="4008040567710660924">Tillad cookies for et bestemt website.</translation> +<translation id="4046123991198612571">Næste nummer</translation> <translation id="4165986682804962316">Indstillinger for websites</translation> <translation id="4226663524361240545">Notifikationer kan få enheden til at vibrere</translation> <translation id="4242533952199664413">Åbn Indstillinger</translation> <translation id="4259722352634471385">Navigationen er blokeret: <ph name="URL" /></translation> <translation id="4278390842282768270">Tilladt</translation> +<translation id="429312253194641664">Et website afspiller medier</translation> <translation id="4433925000917964731">Lite-side leveret af Google</translation> <translation id="4434045419905280838">Pop op-vinduer og omdirigeringer</translation> <translation id="445467742685312942">Tillad, at websites afspiller beskyttet indhold</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Tilbagekald alle tilladelser for enheden</translation> <translation id="4964199952259983386">Hvis du vil give Chrome tilladelse til at bruge AR, skal du også aktivere kameraet i <ph name="BEGIN_LINK" />Android-indstillingerne<ph name="END_LINK" />.</translation> <translation id="497421865427891073">Gå fremad</translation> +<translation id="4996978546172906250">Del via</translation> <translation id="5039804452771397117">Tillad</translation> <translation id="5048398596102334565">Tillad, at websites kan få adgang til bevægelsessensorer (anbefales)</translation> <translation id="5063480226653192405">Databrug</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Ryd</translation> <translation id="6697925417670533197">Aktive downloads</translation> <translation id="6746124502594467657">Flyt ned</translation> +<translation id="6766622839693428701">Stryg ned for at lukke.</translation> <translation id="6782111308708962316">Undgå, at tredjepartswebsites gemmer og læser cookiedata</translation> +<translation id="6790428901817661496">Afspil</translation> <translation id="6818926723028410516">Vælg elementer</translation> <translation id="6864395892908308021">Denne enhed kan ikke læse NFC</translation> <translation id="6910211073230771657">Slettet</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Et website anvender dit kamera</translation> <translation id="7817023149356982970">Du bliver logget ud af dette website.</translation> <translation id="7828557259026017104">Cookies er filer, som oprettes af de websites, du besøger. Websites anvender dem til at huske dine præferencer. Tredjepartscookies oprettes af andre websites. Disse websites ejer noget af indholdet, f.eks. de annoncer eller billeder, der vises på den webside, du besøger.</translation> +<translation id="7835852323729233924">Afspilning af medier</translation> <translation id="7846076177841592234">Annuller valg</translation> <translation id="7846621471902887024">Du bliver logget ud af alle websites.</translation> <translation id="7882806643839505685">Tillad, at et bestemt website afspiller lyd.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Er du sikker på, at du vil slette alle lokale data, herunder cookies, og nulstille alle tilladelser for dette website?</translation> <translation id="8007176423574883786">Deaktiveret på denne enhed</translation> <translation id="802154636333426148">Download mislykkedes</translation> +<translation id="8068648041423924542">Certifikatet kunne ikke vælges.</translation> <translation id="8087000398470557479">Dette indhold er fra <ph name="DOMAIN_NAME" />, som leveres af Google.</translation> <translation id="8116925261070264013">Websites, hvor lyden er slået fra</translation> <translation id="8131740175452115882">Bekræft</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Et website anvender dit kamera og din mikrofon</translation> <translation id="8380167699614421159">Dette website viser påtrængende eller vildledende annoncer</translation> <translation id="8394832520002899662">Tryk for at vende tilbage til websitet</translation> +<translation id="8425213833346101688">Skift</translation> +<translation id="8441146129660941386">Spol tilbage</translation> <translation id="8447861592752582886">Tilbagekald adgangstilladelsen til enheden</translation> <translation id="8463851957836045671">Websitet er hurtigt</translation> <translation id="851751545965956758">Bloker websites fra at oprette forbindelse til enheder</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Bloker cookies for et bestemt website.</translation> <translation id="8959122750345127698">Navigationen er ikke mulig: <ph name="URL" /></translation> <translation id="9019902583201351841">Administreret af dine forældre</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Adgang til din mikrofon</translation> <translation id="965817943346481315">Bloker, hvis websitet viser påtrængende eller vildledende annoncer (anbefales)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_de.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_de.xtb index 3d7a5595e1c..8e20b0e0412 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_de.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_de.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Weiter</translation> <translation id="1242008676835033345">Auf <ph name="WEBSITE_URL" /> eingebettet</translation> <translation id="1272079795634619415">Stoppen</translation> +<translation id="1289742167380433257">Die Bilder auf dieser Seite wurden von Google optimiert, um den Datenverbrauch zu reduzieren.</translation> <translation id="129382876167171263">Hier werden von Websites gespeicherte Dateien angezeigt</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> – <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Website "<ph name="SITE_NAME" />" hinzugefügt</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Nachfragen, bevor Websites erlaubt wird, eine 3D-Karte meiner Umgebung zu erstellen oder die Kameraposition zu verfolgen (empfohlen)</translation> <translation id="2212565012507486665">Cookies zulassen</translation> <translation id="2289270750774289114">Nachfragen, wenn eine Website nach Bluetooth-Geräten in der Nähe suchen möchte (empfohlen)</translation> +<translation id="2315043854645842844">Die clientseitige Zertifikatauswahl wird vom Betriebssystem nicht unterstützt.</translation> <translation id="2359808026110333948">Weiter</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">Download abgeschlossen <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Kopiert</translation> <translation id="2822354292072154809">Möchten Sie wirklich alle Websiteberechtigungen für <ph name="CHOSEN_OBJECT_NAME" /> zurücksetzen?</translation> <translation id="2870560284913253234">Website</translation> +<translation id="2874939134665556319">Vorheriger Titel</translation> <translation id="2910701580606108292">Fragen, bevor die Wiedergabe geschützter Inhalte auf Websites zugelassen wird</translation> <translation id="2913331724188855103">Websites dürfen Cookiedaten speichern und lesen (empfohlen)</translation> <translation id="2968755619301702150">Zertifikats-Viewer</translation> <translation id="300526633675317032">Der gesamte Websitespeicher (<ph name="SIZE_IN_KB" />) wird gelöscht.</translation> +<translation id="301521992641321250">Automatisch blockiert</translation> <translation id="3115898365077584848">Informationen anzeigen</translation> <translation id="3123473560110926937">Auf einigen Websites blockiert</translation> <translation id="3190152372525844641">Berechtigungen für Chrome in den <ph name="BEGIN_LINK" />Android-Einstellungen<ph name="END_LINK" /> aktivieren</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Hintergrundsynchronisierung</translation> <translation id="3822502789641063741">Websitespeicher löschen?</translation> <translation id="385051799172605136">Zurück</translation> +<translation id="3859306556332390985">Nach vorne navigieren</translation> <translation id="3955193568934677022">Wiedergabe geschützter Inhalte auf Websites zulassen (empfohlen)</translation> <translation id="3987993985790029246">Link kopieren</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> von ?</translation> <translation id="4002066346123236978">Titel</translation> <translation id="4008040567710660924">Cookies für eine bestimmte Website werden zugelassen.</translation> +<translation id="4046123991198612571">Nächster Titel</translation> <translation id="4165986682804962316">Website-Einstellungen</translation> <translation id="4226663524361240545">Bei Benachrichtigungen kann das Gerät vibrieren</translation> <translation id="4242533952199664413">Einstellungen öffnen</translation> <translation id="4259722352634471385">Die Navigation zu <ph name="URL" /> ist blockiert.</translation> <translation id="4278390842282768270">Zugelassen</translation> +<translation id="429312253194641664">Eine Website gibt Medien wieder</translation> <translation id="4433925000917964731">Lite-Modus-Seite von Google bereitgestellt</translation> <translation id="4434045419905280838">Pop-ups und Weiterleitungen</translation> <translation id="445467742685312942">Websites erlauben, geschützte Inhalte wiederzugeben</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Alle Berechtigungen für Gerät entziehen</translation> <translation id="4964199952259983386">Damit Chrome AR verwenden kann, muss auch die Kamera in den <ph name="BEGIN_LINK" />Android-Einstellungen<ph name="END_LINK" /> aktiviert sein.</translation> <translation id="497421865427891073">Weiter</translation> +<translation id="4996978546172906250">Teilen über</translation> <translation id="5039804452771397117">Zulassen</translation> <translation id="5048398596102334565">Websites den Zugriff auf Bewegungssensoren erlauben (empfohlen)</translation> <translation id="5063480226653192405">Verwendung</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Löschen</translation> <translation id="6697925417670533197">Aktive Downloads</translation> <translation id="6746124502594467657">Nach unten</translation> +<translation id="6766622839693428701">Zum Schließen nach unten wischen.</translation> <translation id="6782111308708962316">Websites von Drittanbietern am Speichern und Lesen von Cookiedaten hindern</translation> +<translation id="6790428901817661496">Wiedergabe</translation> <translation id="6818926723028410516">Einträge auswählen</translation> <translation id="6864395892908308021">NFC wird von diesem Gerät nicht unterstützt</translation> <translation id="6910211073230771657">Gelöscht</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Eine Website verwendet Ihre Kamera</translation> <translation id="7817023149356982970">Sie werden von dieser Website abgemeldet.</translation> <translation id="7828557259026017104">Cookies sind Dateien, die von Websites erstellt werden, die Sie besuchen. Sie werden zum Speichern Ihrer Einstellungen verwendet. Drittanbieter-Cookies werden von anderen Websites erstellt. Diesen Websites gehören einige der Inhalte, wie z. B. Werbeanzeigen oder Bilder, die Sie auf der besuchten Webseite sehen.</translation> +<translation id="7835852323729233924">Medien werden wiedergegeben</translation> <translation id="7846076177841592234">Auswahl aufheben</translation> <translation id="7846621471902887024">Sie werden von allen Websites abgemeldet.</translation> <translation id="7882806643839505685">Wiedergabe von Ton auf einer bestimmten Website zulassen.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Möchten Sie wirklich alle lokalen Daten einschließlich Cookies löschen und alle Berechtigungen für diese Website zurücksetzen?</translation> <translation id="8007176423574883786">Für dieses Gerät deaktiviert</translation> <translation id="802154636333426148">Downloadfehler</translation> +<translation id="8068648041423924542">Zertifikat kann nicht ausgewählt werden.</translation> <translation id="8087000398470557479">Dieser Inhalt ist von <ph name="DOMAIN_NAME" /> und wurde von Google bereitgestellt.</translation> <translation id="8116925261070264013">Stummgeschaltet</translation> <translation id="8131740175452115882">Bestätigen</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Eine Website verwendet Ihre Kamera und Ihr Mikrofon</translation> <translation id="8380167699614421159">Diese Website zeigt aufdringliche oder irreführende Werbung an</translation> <translation id="8394832520002899662">Tippen, um zur Website zurückzukehren</translation> +<translation id="8425213833346101688">Ändern</translation> +<translation id="8441146129660941386">Zurück navigieren</translation> <translation id="8447861592752582886">Zugriffsberechtigung auf Gerät widerrufen</translation> <translation id="8463851957836045671">Website ist schnell</translation> <translation id="851751545965956758">Verhindern, dass Websites eine Verbindung zu Geräten herstellen</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Cookies für eine bestimmte Website werden blockiert.</translation> <translation id="8959122750345127698">Navigation nicht möglich: <ph name="URL" /> ist nicht erreichbar.</translation> <translation id="9019902583201351841">Von deinen Eltern verwaltet</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Mikrofonzugriff</translation> <translation id="965817943346481315">Blockieren, wenn Website aufdringliche oder irreführende Werbung anzeigt (empfohlen)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_el.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_el.xtb index 30d38b535d8..63d3b55ba1e 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_el.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_el.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Επόμενο</translation> <translation id="1242008676835033345">Ενσωματωμένο σε <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Διακοπή</translation> +<translation id="1289742167380433257">Οι εικόνες αυτής της σελίδας έχουν βελτιστοποιηθεί από την Google για την εξοικονόμηση των δεδομένων σας.</translation> <translation id="129382876167171263">Τα αρχεία που αποθηκεύονται από ιστοτόπους εμφανίζονται εδώ</translation> <translation id="1364532808393826295"><ph name="APP_NAME" />-<ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Προστέθηκε ο ιστότοπος <ph name="SITE_NAME" /></translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Να γίνεται ερώτηση προτού επιτραπεί σε ιστοτόπους η δημιουργία τρισδιάστατου χάρτη του περιβάλλοντα χώρου σας και η παρακολούθηση της θέσης της κάμερας (συνιστάται)</translation> <translation id="2212565012507486665">Αποδοχή cookie</translation> <translation id="2289270750774289114">Να γίνεται ερώτηση όταν ένας ιστότοπος επιθυμεί να εντοπίσει κοντινές συσκευες Bluetooth (συνιστάται)</translation> +<translation id="2315043854645842844">Η επιλογή πιστοποιητικού από τον πελάτη δεν υποστηρίζεται από το λειτουργικό σύστημα.</translation> <translation id="2359808026110333948">Συνέχεια</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">Η λήψη ολοκληρώθηκε <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Αντιγράφ.</translation> <translation id="2822354292072154809">Είστε βέβαοι ότι θέλετε να αναιρεθούν όλες οι άδειες ιστοτόπου για το αντικείμενο <ph name="CHOSEN_OBJECT_NAME" />;</translation> <translation id="2870560284913253234">Ιστότοπος</translation> +<translation id="2874939134665556319">Προηγούμενο κομμάτι</translation> <translation id="2910701580606108292">Να γίνεται ερώτηση προτού επιτραπεί στους ιστοτόπους η αναπαραγωγή προστατευόμενου περιεχομένου</translation> <translation id="2913331724188855103">Να επιτρέπεται στους ιστότοπους η αποθήκευση και η ανάγνωση δεδομένων cookie (συνιστάται)</translation> <translation id="2968755619301702150">Πρόγρ. προβολής πιστοποιητικού</translation> <translation id="300526633675317032">Αυτό θα διαγράψει και τα <ph name="SIZE_IN_KB" /> του αποθηκευτικού χώρου ιστοτόπων.</translation> +<translation id="301521992641321250">Αποκλείστηκε αυτόματα</translation> <translation id="3115898365077584848">Πληροφορίες εκπομπής</translation> <translation id="3123473560110926937">Αποκλεισμός σε ορισμένους ιστοτόπους</translation> <translation id="3190152372525844641">Ενεργοποίηση των αδειών για το Chrome στις <ph name="BEGIN_LINK" />Ρυθμίσεις Android<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Συγχρονισμός παρασκηνίου</translation> <translation id="3822502789641063741">Διαγ.αποθ.χώρου ιστότ.;</translation> <translation id="385051799172605136">Πίσω</translation> +<translation id="3859306556332390985">Αναζήτηση προς τα εμπρός</translation> <translation id="3955193568934677022">Να επιτρέπεται στους ιστοτόπους να αναπαράγουν προστατευμένο περιεχόμενο (συνιστάται)</translation> <translation id="3987993985790029246">Αντ. συνδ.</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">Τίτλος</translation> <translation id="4008040567710660924">Επιτρέπει τα cookie για έναν συγκεκριμένο ιστότοπο.</translation> +<translation id="4046123991198612571">Επόμενο κομμάτι</translation> <translation id="4165986682804962316">Ρυθμίσεις ιστότοπου</translation> <translation id="4226663524361240545">Κατά τη λήψη ειδοποιήσεων ενδέχεται να δονείται η συσκευή</translation> <translation id="4242533952199664413">Ανοίξτε τις ρυθμίσεις</translation> <translation id="4259722352634471385">Αποκλείστηκε η μετάβαση στη διεύθυνση: <ph name="URL" /></translation> <translation id="4278390842282768270">Επιτρέπεται</translation> +<translation id="429312253194641664">Ένας ιστότοπος κάνει αναπαραγωγή μέσων</translation> <translation id="4433925000917964731">Σελίδα Lite που παρέχεται από την Google</translation> <translation id="4434045419905280838">Αναδυόμενα παράθυρα και ανακατευθύνσεις</translation> <translation id="445467742685312942">Να επιτρέπεται στους ιστοτόπους η αναπαραγωγή προστατευμένου περιεχομένου</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Ανάκληση όλων των αδειών για τη συσκευή</translation> <translation id="4964199952259983386">Για να επιτρέπεται στο Chrome να χρησιμοποιεί AR, ενεργοποιήστε επίσης την κάμερα στις <ph name="BEGIN_LINK" />Ρυθμίσεις Android<ph name="END_LINK" />.</translation> <translation id="497421865427891073">Μετάβαση προς τα εμπρός</translation> +<translation id="4996978546172906250">Μοιραστείτε μέσω</translation> <translation id="5039804452771397117">Επιτρέπεται</translation> <translation id="5048398596102334565">Να επιτρέπεται στους ιστοτόπους η πρόσβαση στους αισθητήρες κίνησης (συνιστάται)</translation> <translation id="5063480226653192405">Χρήση</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Διαγραφή</translation> <translation id="6697925417670533197">Ενεργές λήψεις</translation> <translation id="6746124502594467657">Μετακίνηση προς τα κάτω</translation> +<translation id="6766622839693428701">Σύρετε προς τα κάτω για κλείσιμο.</translation> <translation id="6782111308708962316">Αποτροπή αποθήκευσης και ανάγνωσης δεδομένων cookie από ιστότοπους τρίτων</translation> +<translation id="6790428901817661496">Αναπαραγωγή</translation> <translation id="6818926723028410516">Επιλέξτε στοιχεία</translation> <translation id="6864395892908308021">Αυτή η συσκευή δεν μπορεί να διαβάσει NFC</translation> <translation id="6910211073230771657">Διαγράφηκε</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Ένας ιστότοπος χρησιμοποιεί την κάμερά σας.</translation> <translation id="7817023149356982970">Θα αποσυνδεθείτε από αυτόν τον ιστότοπο.</translation> <translation id="7828557259026017104">Τα cookie είναι αρχεία που δημιουργούνται από ιστοτόπους που επισκέπτεστε. Οι ιστότοποι τα χρησιμοποιούν για να απομνημονεύουν τις προτιμήσεις σας. Τα cookie τρίτου μέρους δημιουργούνται από άλλους ιστοτόπους. Αυτοί οι ιστότοποι διαθέτουν κάποιο περιεχόμενο, όπως διαφημίσεις ή εικόνες, το οποίο μπορείτε να δείτε στην ιστοσελίδα που επισκέπτεστε.</translation> +<translation id="7835852323729233924">Αναπαραγωγή πολυμέσων</translation> <translation id="7846076177841592234">Ακύρωση επιλογής</translation> <translation id="7846621471902887024">Θα αποσυνδεθείτε από όλους τους ιστοτόπους.</translation> <translation id="7882806643839505685">Να επιτρέπεται ο ήχος για έναν συγκεκριμένο ιστότοπο.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Είστε βέβαιοι ότι θέλετε να διαγράψετε όλα τα δεδομένα γι' αυτόν τον ιστότοπο, όπως τα cookie, και να επαναφέρετε όλα τα δικαιώματά του;</translation> <translation id="8007176423574883786">Έχει απενεργοποιηθεί για αυτήν τη συσκευή</translation> <translation id="802154636333426148">Η λήψη απέτυχε</translation> +<translation id="8068648041423924542">Δεν είναι δυνατή η επιλογή του πιστοποιητικού.</translation> <translation id="8087000398470557479">Αυτό το περιεχόμενο προέρχεται από το <ph name="DOMAIN_NAME" /> και παρέχεται από την Google.</translation> <translation id="8116925261070264013">Σε σίγαση</translation> <translation id="8131740175452115882">Επιβεβαίωση</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Ένας ιστότοπος χρησιμοποιεί την κάμερα και το μικρόφωνό σας.</translation> <translation id="8380167699614421159">Αυτός ο ιστότοπος εμφανίζει παρεμβατικές ή παραπλανητικές διαφημίσεις</translation> <translation id="8394832520002899662">Πατήστε για επιστροφή στον ιστότοπο</translation> +<translation id="8425213833346101688">Αλλαγή</translation> +<translation id="8441146129660941386">Αναζήτηση προς τα πίσω</translation> <translation id="8447861592752582886">Ανάκληση άδειας συσκευής</translation> <translation id="8463851957836045671">Ο ιστότοπος είναι γρήγορος</translation> <translation id="851751545965956758">Αποκλεισμός ιστοτόπων από τη σύνδεση σε συσκευές</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Αποκλεισμός cookie για έναν συγκεκριμένο ιστοτόπο.</translation> <translation id="8959122750345127698">Δεν είναι δυνατή η μετάβαση στη διεύθυνση: <ph name="URL" /></translation> <translation id="9019902583201351841">Διαχειρίζεται από τους γονείς σου</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Πρόσβαση στο μικρόφωνό σας</translation> <translation id="965817943346481315">Αποκλεισμός εάν ο ιστότοπος εμφανίζει παρεμβατικές ή παραπλανητικές διαφημίσεις (συνιστάται)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_en-GB.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_en-GB.xtb index e96624653f8..a8b9abf20d5 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_en-GB.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_en-GB.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Next</translation> <translation id="1242008676835033345">Embedded on <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Stop</translation> +<translation id="1289742167380433257">To save you data, this page's images have been optimised by Google.</translation> <translation id="129382876167171263">Files saved by websites appear here</translation> <translation id="1364532808393826295"><ph name="APP_NAME" />–<ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Site <ph name="SITE_NAME" /> added</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Ask before allowing sites to create a 3D map of your surroundings or track camera position (recommended)</translation> <translation id="2212565012507486665">Allow cookies</translation> <translation id="2289270750774289114">Ask when a site wants to discover nearby Bluetooth devices (recommended)</translation> +<translation id="2315043854645842844">Client side certificate selection is not supported by the operating system.</translation> <translation id="2359808026110333948">Continue</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">Download complete <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Copied</translation> <translation id="2822354292072154809">Are you sure that you want to reset all site permissions for <ph name="CHOSEN_OBJECT_NAME" />?</translation> <translation id="2870560284913253234">Site</translation> +<translation id="2874939134665556319">Previous track</translation> <translation id="2910701580606108292">Ask before allowing sites to play protected content</translation> <translation id="2913331724188855103">Allow sites to save and read cookie data (recommended)</translation> <translation id="2968755619301702150">Certificate viewer</translation> <translation id="300526633675317032">This will clear all <ph name="SIZE_IN_KB" /> of website storage.</translation> +<translation id="301521992641321250">Automatically blocked</translation> <translation id="3115898365077584848">Show info</translation> <translation id="3123473560110926937">Blocked on some sites</translation> <translation id="3190152372525844641">Turn on permissions for Chrome in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Background sync</translation> <translation id="3822502789641063741">Clear site storage?</translation> <translation id="385051799172605136">Back</translation> +<translation id="3859306556332390985">Seek forward</translation> <translation id="3955193568934677022">Allow sites to play protected content (recommended)</translation> <translation id="3987993985790029246">Copy link</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> <translation id="4002066346123236978">Title</translation> <translation id="4008040567710660924">Allow cookies for a specific site.</translation> +<translation id="4046123991198612571">Next track</translation> <translation id="4165986682804962316">Site settings</translation> <translation id="4226663524361240545">Notifications may vibrate the device</translation> <translation id="4242533952199664413">Open settings</translation> <translation id="4259722352634471385">Navigation is blocked: <ph name="URL" /></translation> <translation id="4278390842282768270">Allowed</translation> +<translation id="429312253194641664">A site is playing media</translation> <translation id="4433925000917964731">Lite page provided by Google</translation> <translation id="4434045419905280838">Pop-ups and redirects</translation> <translation id="445467742685312942">Allow sites to play protected content</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Revoke all permissions for device</translation> <translation id="4964199952259983386">To let Chrome use AR, also turn on the camera in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> <translation id="497421865427891073">go forward</translation> +<translation id="4996978546172906250">Share via</translation> <translation id="5039804452771397117">Allow</translation> <translation id="5048398596102334565">Allow sites to access motion sensors (recommended)</translation> <translation id="5063480226653192405">Usage</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Clear</translation> <translation id="6697925417670533197">Active downloads</translation> <translation id="6746124502594467657">Move down</translation> +<translation id="6766622839693428701">Swipe down to close.</translation> <translation id="6782111308708962316">Prevent third-party websites from saving and reading cookie data</translation> +<translation id="6790428901817661496">Play</translation> <translation id="6818926723028410516">Select items</translation> <translation id="6864395892908308021">This device can't read NFC</translation> <translation id="6910211073230771657">Deleted</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">A site is using your camera</translation> <translation id="7817023149356982970">You'll be signed out of this site.</translation> <translation id="7828557259026017104">Cookies are files created by websites that you visit. Sites use them to remember your preferences. Third-party cookies are created by other sites. These sites own some of the content, like ads or images, that you see on the web page that you visit.</translation> +<translation id="7835852323729233924">Playing media</translation> <translation id="7846076177841592234">Cancel selection</translation> <translation id="7846621471902887024">You'll be signed out of all sites.</translation> <translation id="7882806643839505685">Allow sound for a specific site.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Are you sure that you want to clear all local data, including cookies, and reset all permissions for this website?</translation> <translation id="8007176423574883786">Turned off for this device</translation> <translation id="802154636333426148">Download failed</translation> +<translation id="8068648041423924542">Unable to select certificate.</translation> <translation id="8087000398470557479">This content is from <ph name="DOMAIN_NAME" />, delivered by Google.</translation> <translation id="8116925261070264013">Muted</translation> <translation id="8131740175452115882">Confirm</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">A site is using your camera and microphone</translation> <translation id="8380167699614421159">This site shows intrusive or misleading ads</translation> <translation id="8394832520002899662">Tap to return to the site</translation> +<translation id="8425213833346101688">Change</translation> +<translation id="8441146129660941386">Seek backward</translation> <translation id="8447861592752582886">Revoke device permission</translation> <translation id="8463851957836045671">Site is fast</translation> <translation id="851751545965956758">Block sites from connecting to devices</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Block cookies for a specific site.</translation> <translation id="8959122750345127698">Navigation is unreachable: <ph name="URL" /></translation> <translation id="9019902583201351841">Managed by your parents</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Access your microphone</translation> <translation id="965817943346481315">Block if site shows intrusive or misleading ads (recommended)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_es-419.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_es-419.xtb index 930bffc3e94..212c7e84c23 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_es-419.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_es-419.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Siguiente</translation> <translation id="1242008676835033345">Incorporado en <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Interrumpir</translation> +<translation id="1289742167380433257">Para ahorrar datos, Google optimizó las imágenes de esta página.</translation> <translation id="129382876167171263">Aquí se mostrarán los archivos que guarden los sitios web</translation> <translation id="1364532808393826295"><ph name="APP_NAME" />: <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Se agregó el sitio <ph name="SITE_NAME" />.</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Preguntar antes de permitir que los sitios creen un mapa 3D de tu entorno o hagan un seguimiento de la posición de la cámara (recomendado)</translation> <translation id="2212565012507486665">Permitir cookies</translation> <translation id="2289270750774289114">Preguntarme cuando un sitio intente conectarse a dispositivos Bluetooth cercanos (recomendado)</translation> +<translation id="2315043854645842844">El sistema operativo no admite la selección de certificados del lado del cliente.</translation> <translation id="2359808026110333948">Continuar</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">Se completó la descarga <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Copiado</translation> <translation id="2822354292072154809">¿Confirmas que quieres restablecer todos los permisos de sitios para <ph name="CHOSEN_OBJECT_NAME" />?</translation> <translation id="2870560284913253234">Sitio</translation> +<translation id="2874939134665556319">Pista anterior</translation> <translation id="2910701580606108292">Preguntar antes de permitir que los sitios reproduzcan contenido protegido</translation> <translation id="2913331724188855103">Permitir que todos los sitios guarden y lean datos de cookies (recomendado)</translation> <translation id="2968755619301702150">Visualizador de certificados</translation> <translation id="300526633675317032">Se borrarán <ph name="SIZE_IN_KB" /> del almacenamiento del sitio web.</translation> +<translation id="301521992641321250">Bloqueado de forma automática</translation> <translation id="3115898365077584848">Mostrar información</translation> <translation id="3123473560110926937">Bloqueados en algunos sitios</translation> <translation id="3190152372525844641">Activa los permisos para Chrome en <ph name="BEGIN_LINK" />Configuración de Android<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Sincronización en segundo plano</translation> <translation id="3822502789641063741">¿Borrar el almacenamiento de sitios?</translation> <translation id="385051799172605136">Atrás</translation> +<translation id="3859306556332390985">Buscar más adelante</translation> <translation id="3955193568934677022">Permitir que los sitios reproduzcan contenido protegido (recomendado)</translation> <translation id="3987993985790029246">Copiar vínculo</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> <translation id="4002066346123236978">Título</translation> <translation id="4008040567710660924">Permite las cookies para un sitio específico.</translation> +<translation id="4046123991198612571">Siguiente pista</translation> <translation id="4165986682804962316">Configuración de sitios</translation> <translation id="4226663524361240545">Es posible que las notificaciones hagan vibrar el dispositivo</translation> <translation id="4242533952199664413">Abrir la configuración</translation> <translation id="4259722352634471385">Navegación bloqueada: <ph name="URL" /></translation> <translation id="4278390842282768270">Permitido</translation> +<translation id="429312253194641664">Un sitio está reproduciendo contenido multimedia</translation> <translation id="4433925000917964731">Google proporcionó la página básica</translation> <translation id="4434045419905280838">Ventanas emergentes y redireccionamientos</translation> <translation id="445467742685312942">Permitir que los sitios reproduzcan contenido protegido</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Revocar todos los permisos del dispositivo</translation> <translation id="4964199952259983386">Para permitir el uso de la RA en Chrome, también debes activar la cámara en la <ph name="BEGIN_LINK" />Configuración de Android<ph name="END_LINK" />.</translation> <translation id="497421865427891073">Avanzar</translation> +<translation id="4996978546172906250">Compartir mediante</translation> <translation id="5039804452771397117">Permitir</translation> <translation id="5048398596102334565">Permitir que los sitios accedan a los sensores de movimiento (recomendado)</translation> <translation id="5063480226653192405">Uso</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Borrar</translation> <translation id="6697925417670533197">Descargas activas</translation> <translation id="6746124502594467657">Mover hacia abajo</translation> +<translation id="6766622839693428701">Desliza hacia abajo para cerrar.</translation> <translation id="6782111308708962316">Evitar que los sitios web de terceros guarden y lean datos de cookies</translation> +<translation id="6790428901817661496">Reproducir</translation> <translation id="6818926723028410516">Seleccionar elementos</translation> <translation id="6864395892908308021">Este dispositivo no puede leer NFC</translation> <translation id="6910211073230771657">Eliminado</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Un sitio está utilizando la cámara</translation> <translation id="7817023149356982970">Saldrás de este sitio.</translation> <translation id="7828557259026017104">Las cookies son archivos que crean los sitios web que visitas para recordar tus preferencias. Las cookies de terceros son las que se generan desde otros sitios a los cuales pertenece parte del contenido que ves en la página web que visitas (como anuncios o imágenes).</translation> +<translation id="7835852323729233924">Reproduciendo contenido multimedia</translation> <translation id="7846076177841592234">Cancelar la selección</translation> <translation id="7846621471902887024">Saldrás de todos los sitios.</translation> <translation id="7882806643839505685">Habilitar el sonido de un sitio específico</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">¿Quieres eliminar todos los datos locales de este sitio web, incluidas las cookies, y restablecer todos los permisos?</translation> <translation id="8007176423574883786">Desactivado para este dispositivo</translation> <translation id="802154636333426148">Error en la descarga</translation> +<translation id="8068648041423924542">No es posible seleccionar un certificado</translation> <translation id="8087000398470557479">Este contenido es de <ph name="DOMAIN_NAME" />, publicado por Google.</translation> <translation id="8116925261070264013">Silenciados</translation> <translation id="8131740175452115882">Confirmar</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Un sitio está utilizando la cámara y el micrófono</translation> <translation id="8380167699614421159">Este sitio muestra anuncios intrusivos o engañosos</translation> <translation id="8394832520002899662">Presiona para volver al sitio</translation> +<translation id="8425213833346101688">Cambiar</translation> +<translation id="8441146129660941386">Buscar más atrás</translation> <translation id="8447861592752582886">Revocar permiso para el dispositivo</translation> <translation id="8463851957836045671">El sitio es rápido</translation> <translation id="851751545965956758">Impedir que los sitios se conecten a los dispositivos</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Bloquea las cookies en un sitio específico.</translation> <translation id="8959122750345127698">Navegación inaccesible: <ph name="URL" /></translation> <translation id="9019902583201351841">Administrado por tus padres</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Acceso al micrófono</translation> <translation id="965817943346481315">Bloquear si el sitio muestra anuncios intrusivos o engañosos (opción recomendada)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_es.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_es.xtb index b53e04b414b..0f4f79ac66c 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_es.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_es.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Siguiente</translation> <translation id="1242008676835033345">Insertada en <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Interrumpir</translation> +<translation id="1289742167380433257">Para ahorrar datos, Google ha optimizado las imágenes de esta página.</translation> <translation id="129382876167171263">Los archivos que guarden los sitios web aparecerán aquí</translation> <translation id="1364532808393826295"><ph name="APP_NAME" />: <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Se ha añadido el sitio <ph name="SITE_NAME" /></translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Preguntar antes de permitir que los sitios web creen un mapa 3D de tu entorno o hagan un seguimiento de la posición de la cámara (recomendado)</translation> <translation id="2212565012507486665">Permitir cookies</translation> <translation id="2289270750774289114">Preguntar cuando un sitio web quiera buscar dispositivos Bluetooth cercanos (recomendado)</translation> +<translation id="2315043854645842844">El sistema operativo no admite la selección de certificados de cliente.</translation> <translation id="2359808026110333948">Continuar</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">Descarga finalizada <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Copiado</translation> <translation id="2822354292072154809">¿Seguro que quieres restablecer todos los permisos de los sitios web de <ph name="CHOSEN_OBJECT_NAME" />?</translation> <translation id="2870560284913253234">Sitio</translation> +<translation id="2874939134665556319">Pista anterior</translation> <translation id="2910701580606108292">Preguntar antes de permitir que los sitios web reproduzcan contenido protegido</translation> <translation id="2913331724188855103">Permitir que los sitios guarden y lean datos de cookies (recomendado)</translation> <translation id="2968755619301702150">Visor de certificados</translation> <translation id="300526633675317032">Se borrarán los <ph name="SIZE_IN_KB" /> de almacenamiento del sitio web.</translation> +<translation id="301521992641321250">Bloqueado automáticamente</translation> <translation id="3115898365077584848">Mostrar información</translation> <translation id="3123473560110926937">Bloqueados en algunos sitios web</translation> <translation id="3190152372525844641">Activa los permisos para Chrome en los <ph name="BEGIN_LINK" />ajustes de Android<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Sincronización en segundo plano</translation> <translation id="3822502789641063741">¿Borrar almacenamiento web?</translation> <translation id="385051799172605136">Volver</translation> +<translation id="3859306556332390985">Buscar hacia delante</translation> <translation id="3955193568934677022">Permitir que los sitios web reproduzcan contenido protegido (recomendado)</translation> <translation id="3987993985790029246">Copiar enlace</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> <translation id="4002066346123236978">Título</translation> <translation id="4008040567710660924">Permitir cookies en un sitio web específico.</translation> +<translation id="4046123991198612571">Pista siguiente</translation> <translation id="4165986682804962316">Configuración de sitios web</translation> <translation id="4226663524361240545">Es posible que las notificaciones hagan que el dispositivo vibre</translation> <translation id="4242533952199664413">Abrir Configuración</translation> <translation id="4259722352634471385">Se ha bloqueado la navegación: <ph name="URL" /></translation> <translation id="4278390842282768270">Permitido</translation> +<translation id="429312253194641664">Un sitio web está reproduciendo elementos multimedia</translation> <translation id="4433925000917964731">Página básica ofrecida por Google</translation> <translation id="4434045419905280838">Ventanas emergentes y redirecciones</translation> <translation id="445467742685312942">Permitir que los sitios web reproduzcan contenido protegido</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Revocar todos los permisos de este dispositivo</translation> <translation id="4964199952259983386">Para que Chrome pueda usar la realidad aumentada, activa la cámara también en los <ph name="BEGIN_LINK" />ajustes de Android<ph name="END_LINK" />.</translation> <translation id="497421865427891073">Avanzar</translation> +<translation id="4996978546172906250">Compartir a través de</translation> <translation id="5039804452771397117">Permitir</translation> <translation id="5048398596102334565">Permitir que los sitios web accedan a los sensores de movimiento (recomendado)</translation> <translation id="5063480226653192405">Uso</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Eliminar</translation> <translation id="6697925417670533197">Descargas activas</translation> <translation id="6746124502594467657">Bajar</translation> +<translation id="6766622839693428701">Desliza el dedo hacia abajo para cerrarla.</translation> <translation id="6782111308708962316">Impedir que los sitios web de terceros guarden y consulten datos de cookies</translation> +<translation id="6790428901817661496">Reproducir</translation> <translation id="6818926723028410516">Seleccionar elementos</translation> <translation id="6864395892908308021">Este dispositivo no puede leer NFC</translation> <translation id="6910211073230771657">Eliminado</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Un sitio web está usando tu cámara</translation> <translation id="7817023149356982970">Se cerrará tu sesión en este sitio web.</translation> <translation id="7828557259026017104">Las cookies son archivos que crean los sitios web que visitas. Estos las usan para recordar tus preferencias. Las cookies de terceros las crean otros sitios web. Parte del contenido que ves en la página web que visitas, como anuncios o imágenes, pertenece a esos otros sitios web.</translation> +<translation id="7835852323729233924">Reproduciendo contenido multimedia</translation> <translation id="7846076177841592234">Cancelar selección</translation> <translation id="7846621471902887024">Se cerrarán tus sesiones en todos los sitios web.</translation> <translation id="7882806643839505685">Permite que se reproduzcan sonidos en un sitio web específico.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">¿Seguro que quieres borrar todos los datos locales, incluidas las cookies, y restablecer todos los permisos de este sitio web?</translation> <translation id="8007176423574883786">Desactivada para este dispositivo</translation> <translation id="802154636333426148">No se ha podido descargar el archivo</translation> +<translation id="8068648041423924542">No se puede seleccionar el certificado.</translation> <translation id="8087000398470557479">Este contenido procede de <ph name="DOMAIN_NAME" />, publicado por Google.</translation> <translation id="8116925261070264013">Silenciados</translation> <translation id="8131740175452115882">Confirmar</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Un sitio web está usando tu cámara y tu micrófono</translation> <translation id="8380167699614421159">El sitio web muestra anuncios invasivos o engañosos</translation> <translation id="8394832520002899662">Toca para volver al sitio web</translation> +<translation id="8425213833346101688">Cambiar</translation> +<translation id="8441146129660941386">Buscar hacia atrás</translation> <translation id="8447861592752582886">Revocar permiso de dispositivo</translation> <translation id="8463851957836045671">El sitio web es rápido</translation> <translation id="851751545965956758">No permitir que los sitios web se conecten a dispositivos</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Bloquear las cookies de un sitio web específico.</translation> <translation id="8959122750345127698">No se puede realizar la navegación: <ph name="URL" /></translation> <translation id="9019902583201351841">Administrado por tus padres</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Acceder al micrófono</translation> <translation id="965817943346481315">Bloquear si el sitio web muestra anuncios invasivos o engañosos (recomendado)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_et.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_et.xtb index debba371a06..ca9e3851409 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_et.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_et.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Järgmine</translation> <translation id="1242008676835033345">Manustatud aadressil <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Peata</translation> +<translation id="1289742167380433257">Andmemahu säästmiseks optimeerib Google selle lehe kujutisi.</translation> <translation id="129382876167171263">Veebisaitide salvestatud failid kuvatakse siin</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> – <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676"><ph name="SITE_NAME" /> on lisatud</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Küsi enne saitidele loa andmist mind ümbritsevast 3D-kaardi loomiseks või kaamera asendi jälgimiseks (soovitatav)</translation> <translation id="2212565012507486665">Luba küpsisefailid</translation> <translation id="2289270750774289114">Küsi, kui sait soovib läheduses asuvaid Bluetoothi seadmeid tuvastada (soovitatav)</translation> +<translation id="2315043854645842844">Operatsioonisüsteem ei toeta kliendipoolset sertifikaadi valimist.</translation> <translation id="2359808026110333948">Jätka</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">Allalaadimine jõudis lõpule: <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Kopeeritud</translation> <translation id="2822354292072154809">Kas soovite objekti <ph name="CHOSEN_OBJECT_NAME" /> jaoks kindlasti lähtestada kõik saidi load?</translation> <translation id="2870560284913253234">Sait</translation> +<translation id="2874939134665556319">Eelmine lugu</translation> <translation id="2910701580606108292">Küsi enne saitidel kaitstud sisu esitamise lubamist</translation> <translation id="2913331724188855103">Lubab saitidel salvestada küpsiseid ja lugeda küpsiste andmeid (soovitatav)</translation> <translation id="2968755619301702150">Sertifikaadikuvaja</translation> <translation id="300526633675317032">See tühjendab veebisaidi salvestusruumi mahuga <ph name="SIZE_IN_KB" />.</translation> +<translation id="301521992641321250">Automaatselt blokeeritud</translation> <translation id="3115898365077584848">Kuva teave</translation> <translation id="3123473560110926937">Blokeeritud teatud saitidel</translation> <translation id="3190152372525844641">Lülita <ph name="BEGIN_LINK" />Android-seadetes<ph name="END_LINK" /> sisse load Chrome'ile.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Taustal sünkroonimine</translation> <translation id="3822502789641063741">Kas tühj. saidi salvestusruum?</translation> <translation id="385051799172605136">Tagasi</translation> +<translation id="3859306556332390985">Keri edasi</translation> <translation id="3955193568934677022">Luba saitidel esitada kaitstud sisu (soovitatav)</translation> <translation id="3987993985790029246">Kop. link</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">Pealkiri</translation> <translation id="4008040567710660924">Lubage konkreetse saidi küpsisefailid.</translation> +<translation id="4046123991198612571">Järgmine lugu</translation> <translation id="4165986682804962316">Saidi seaded</translation> <translation id="4226663524361240545">Seade võib märguannete korral vibreerida</translation> <translation id="4242533952199664413">Ava seaded</translation> <translation id="4259722352634471385">Navigeerimine on blokeeritud: <ph name="URL" /></translation> <translation id="4278390842282768270">Lubatud</translation> +<translation id="429312253194641664">Sait esitab meediasisu</translation> <translation id="4433925000917964731">Lihtsustatud lehte pakub Google</translation> <translation id="4434045419905280838">Hüpikaknad ja ümbersuunamised</translation> <translation id="445467742685312942">Saitidel on lubatud esitada kaitstud sisu</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Seadme puhul kõigi lubade tühistamine</translation> <translation id="4964199952259983386">Selleks et Chrome saaks AR-i kasutada, lülitage <ph name="BEGIN_LINK" />Androidi seadetes<ph name="END_LINK" /> sisse ka kaamera.</translation> <translation id="497421865427891073">Edasiminek</translation> +<translation id="4996978546172906250">Jagamine:</translation> <translation id="5039804452771397117">Luba</translation> <translation id="5048398596102334565">Luba saitide jaoks juurdepääs liikumisanduritele (soovitatav)</translation> <translation id="5063480226653192405">Kasutus</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Tühjenda</translation> <translation id="6697925417670533197">Aktiivsed allalaadimised</translation> <translation id="6746124502594467657">Liiguta alla</translation> +<translation id="6766622839693428701">Sulgemiseks pühkige alla.</translation> <translation id="6782111308708962316">Keela kolmanda osapoole veebisaitidele küpsisefailide andmete salvestamine ja lugemine</translation> +<translation id="6790428901817661496">Esita</translation> <translation id="6818926723028410516">Valige üksused</translation> <translation id="6864395892908308021">See seade ei saa NFC andmeid lugeda</translation> <translation id="6910211073230771657">Kustutatud</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Sait kasutab teie kaamerat</translation> <translation id="7817023149356982970">Teid logitakse sellelt saidilt välja.</translation> <translation id="7828557259026017104">Küpsisefailid on failid, mille on loonud teie külastatud veebisaidid. Saidid kasutavad neid teie eelistuste meeldejätmiseks. Kolmanda osapoole küpsisefailid loovad teised saidid. Need saidid omavad külastatud veebisaidil kuvatud sisu, nt reklaame või pilte.</translation> +<translation id="7835852323729233924">Meedia esitamine</translation> <translation id="7846076177841592234">Tühista valik</translation> <translation id="7846621471902887024">Teid logitakse kõikidelt saitidelt välja.</translation> <translation id="7882806643839505685">Konkreetse saidi heli lubamine.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Kas soovite kindlasti kustutada kõik kohalikud andmed (sh küpsised) ja lähtestada kõik selle veebisaidi load?</translation> <translation id="8007176423574883786">Selle seadme puhul on välja lülitatud</translation> <translation id="802154636333426148">Allalaadimine ebaõnnestus</translation> +<translation id="8068648041423924542">Sertifikaati ei saa valida.</translation> <translation id="8087000398470557479">See sisu pärineb domeenilt <ph name="DOMAIN_NAME" /> ja seda pakub Google.</translation> <translation id="8116925261070264013">Vaigistatud</translation> <translation id="8131740175452115882">Kinnita</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Sait kasutab teie kaamerat ja mikrofoni</translation> <translation id="8380167699614421159">Sait kuvab sekkuvaid või eksitavaid reklaame.</translation> <translation id="8394832520002899662">Puudutage saidile naasmiseks</translation> +<translation id="8425213833346101688">Muuda</translation> +<translation id="8441146129660941386">Keri tagasi</translation> <translation id="8447861592752582886">Seadme loa tühistamine</translation> <translation id="8463851957836045671">Sait on kiire</translation> <translation id="851751545965956758">Blokeeri saitidel seadmetega ühenduse loomine</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Blokeerige konkreetse saidi küpsisefailid.</translation> <translation id="8959122750345127698">Navigeerimine ei ole saadaval: <ph name="URL" /></translation> <translation id="9019902583201351841">Vanemate hallatud</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Juurdepääs mikrofonile</translation> <translation id="965817943346481315">Blokeeri, kui sait kuvab sekkuvaid või eksitavaid reklaame (soovitatav)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_eu.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_eu.xtb index be6e665de42..77ac286199d 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_eu.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_eu.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Hurrengoa</translation> <translation id="1242008676835033345"><ph name="WEBSITE_URL" /> helbidean kapsulatua</translation> <translation id="1272079795634619415">Gelditu</translation> +<translation id="1289742167380433257">Datuak aurrezteko, orri honetako irudiak optimizatu egin ditu Google-k.</translation> <translation id="129382876167171263">Webguneek gordetako fitxategiak hemen agertzen dira</translation> <translation id="1364532808393826295"><ph name="APP_NAME" />: <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676"><ph name="SITE_NAME" /> webgunea gehitu da</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Eskatu zure baimena webguneei inguruaren 3D-ko mapa bat sortu edo kameraren posizioaren jarraipena egiteko baimena eman aurretik (gomendatua)</translation> <translation id="2212565012507486665">Onartu cookieak</translation> <translation id="2289270750774289114">Eskatu nire baimena webgune batek inguruko Bluetooth bidezko gailuak bilatu nahi dituenean (gomendatua)</translation> +<translation id="2315043854645842844">Sistema eragileak ez du onartzen bezeroarentzako ziurtagiria hautatzea.</translation> <translation id="2359808026110333948">Jarraitu</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">Deskargatu da <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Kopiatuta</translation> <translation id="2822354292072154809">Ziur <ph name="CHOSEN_OBJECT_NAME" /> objektuaren webgune-baimen guztiak berrezarri nahi dituzula?</translation> <translation id="2870560284913253234">Webgunea</translation> +<translation id="2874939134665556319">Aurreko pista</translation> <translation id="2910701580606108292">Webguneei eduki babestua erreproduzitzeko baimena eman aurretik, eskatu onespena</translation> <translation id="2913331724188855103">Baimendu webguneei cookieen datuak gordetzea eta irakurtzea (gomendatua)</translation> <translation id="2968755619301702150">Ziurtagiri-ikustailea</translation> <translation id="300526633675317032"><ph name="SIZE_IN_KB" /> ezabatuko dira webguneen datuetatik.</translation> +<translation id="301521992641321250">Automatikoki blokeatuta</translation> <translation id="3115898365077584848">Erakutsi informazioa</translation> <translation id="3123473560110926937">Webgune batzuetan blokeatu dira iragarkiak</translation> <translation id="3190152372525844641">Aktibatu Chrome-rako baimenak <ph name="BEGIN_LINK" />Android-en ezarpenetan<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Atzeko planoko sinkronizazioa</translation> <translation id="3822502789641063741">Webgune-datuak garbitu?</translation> <translation id="385051799172605136">Atzera</translation> +<translation id="3859306556332390985">Aurreratu</translation> <translation id="3955193568934677022">Baimendu webguneei eduki babestua erreproduzitzea (gomendatua)</translation> <translation id="3987993985790029246">Kopiatu esteka</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">Izena</translation> <translation id="4008040567710660924">Onartu webgune zehatz baten cookieak.</translation> +<translation id="4046123991198612571">Hurrengo pista</translation> <translation id="4165986682804962316">Webgunearen ezarpenak</translation> <translation id="4226663524361240545">Gailua dardararaz dezakete jakinarazpenek</translation> <translation id="4242533952199664413">Ireki ezarpenak</translation> <translation id="4259722352634471385"><ph name="URL" /> orrira joateko aukera blokeatuta dago</translation> <translation id="4278390842282768270">Baimenduta</translation> +<translation id="429312253194641664">Webgune bat multimedia-edukia erreproduzitzen ari da</translation> <translation id="4433925000917964731">Google-k eskainitako oinarrizko orria</translation> <translation id="4434045419905280838">Leiho gainerak. / Birbideratzeak</translation> <translation id="445467742685312942">Baimendu webguneei eduki babestua erreproduzitzea</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Baliogabetu gailuaren baimen guztiak</translation> <translation id="4964199952259983386">Chrome-k errealitate areagotua erabil dezan, aktibatu kamera atzitzeko baimena <ph name="BEGIN_LINK" />Android-en ezarpenetan<ph name="END_LINK" />.</translation> <translation id="497421865427891073">Aurrera</translation> +<translation id="4996978546172906250">Partekatu honen bidez:</translation> <translation id="5039804452771397117">Baimendu</translation> <translation id="5048398596102334565">Eman mugimendu-sentsoreak atzitzeko baimena webguneei (gomendatua)</translation> <translation id="5063480226653192405">Erabilera</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Garbitu</translation> <translation id="6697925417670533197">Deskarga aktiboak</translation> <translation id="6746124502594467657">Eraman behera</translation> +<translation id="6766622839693428701">Pasatu hatza behera ixteko.</translation> <translation id="6782111308708962316">Eragotzi hirugarrenen webguneek cookieen datuak gordetzea eta irakurtzea</translation> +<translation id="6790428901817661496">Erreproduzitu</translation> <translation id="6818926723028410516">Hautatu elementuak</translation> <translation id="6864395892908308021">Gailu honek ezin du irakurri NFC</translation> <translation id="6910211073230771657">Ezabatu egin da</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Webgune bat kamera erabiltzen ari da</translation> <translation id="7817023149356982970">Webgune honetako saioa amaitu egingo da.</translation> <translation id="7828557259026017104">Bisitatzen dituzun webguneek sortutako fitxategiak dira cookieak. Zure hobespenak gogoratzeko erabiltzen dituzte webguneek. Hirugarrenen cookieak beste webgune batzuek sortzen dituzte. Bisitatzen duzun web-orrian ikusten dituzun eduki batzuen jabeak dira webgune horiek; adibidez, iragarkienak edo irudienak.</translation> +<translation id="7835852323729233924">Multimedia-edukia erreproduzitzen</translation> <translation id="7846076177841592234">Utzi hautapena bertan behera</translation> <translation id="7846621471902887024">Webgune guztietan amaituko da saioa.</translation> <translation id="7882806643839505685">Baimendu webgune jakin baten audioa.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Ziur webgune honek gailuan ezarritako datu guztiak (cookieak barne) ezabatu eta baimen guztiak berrezarri nahi dituzula?</translation> <translation id="8007176423574883786">Desaktibatu egin da gailu honetan</translation> <translation id="802154636333426148">Ezin izan da deskargatu</translation> +<translation id="8068648041423924542">Ezin da hautatu ziurtagiria.</translation> <translation id="8087000398470557479">Eduki hau <ph name="DOMAIN_NAME" /> domeinukoa da eta Google-k eskaintzen du.</translation> <translation id="8116925261070264013">Audioa desaktibatuta</translation> <translation id="8131740175452115882">Berretsi</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Webgune bat kamera eta mikrofonoa erabiltzen ari da</translation> <translation id="8380167699614421159">Webgune honek iragarki oztopatzaile edo iruzurrezkoak erakusten ditu</translation> <translation id="8394832520002899662">Sakatu hau webgunera itzultzeko</translation> +<translation id="8425213833346101688">Aldatu</translation> +<translation id="8441146129660941386">Atzeratu</translation> <translation id="8447861592752582886">Kendu gailua atzitzeko baimena</translation> <translation id="8463851957836045671">Webgunea bizkorra da</translation> <translation id="851751545965956758">Ez utzi webguneei gailuekin konektatzen</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Blokeatu webgune jakin bateko cookieak.</translation> <translation id="8959122750345127698">Ezin da joan <ph name="URL" /> orrira</translation> <translation id="9019902583201351841">Gurasoek kudeatuta</translation> +<translation id="9074739597929991885">Bluetooth-a</translation> <translation id="945632385593298557">Atzitu mikrofonoa</translation> <translation id="965817943346481315">Webguneak iragarki oztopatzaileak erakusten baditu, blokea itzazu (gomendatua)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_fa.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_fa.xtb index cf58c1752f7..8c47ba88f81 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_fa.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_fa.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">بعدی</translation> <translation id="1242008676835033345">جاسازیشده در <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">توقف</translation> +<translation id="1289742167380433257">برای صرفهجویی درمصرف داده، Google تصاویر این صفحه را بهینهسازی کرده است.</translation> <translation id="129382876167171263">فایلهایی را که وبسایتها ذخیره کردهاند، در اینجا نمایش داده میشود</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> - <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">سایت <ph name="SITE_NAME" /> اضافه شد</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">قبل از اینکه به سایتها اجازه داده شود نقشه سهبعدی از محیط ایجاد کنند یا موقعیت دوربین را ردیابی کنند سؤال شود (توصیه میشود)</translation> <translation id="2212565012507486665">مجاز کردن کوکی ها</translation> <translation id="2289270750774289114">وقتی سایتی میخواهد دستگاههای بلوتوث اطراف را پیدا کند، سؤال شود (توصیه میشود)</translation> +<translation id="2315043854645842844">انتخاب گواهی سمت کلاینت توسط سیستمعامل پشتیبانی نمیشود.</translation> <translation id="2359808026110333948">ادامه</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> مگابایت</translation> <translation id="2434158240863470628">بارگیری کامل شد <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">کپی شد</translation> <translation id="2822354292072154809">مطمئناید میخواهید همه مجوزهای سایت مربوط به <ph name="CHOSEN_OBJECT_NAME" /> را بازنشانی کنید؟</translation> <translation id="2870560284913253234">سایت</translation> +<translation id="2874939134665556319">آهنگ قبلی</translation> <translation id="2910701580606108292">قبل از اجازه دادن به سایتها برای پخش محتوای محافظتشده سؤال شود</translation> <translation id="2913331724188855103">سایتها مجاز به ذخیره و خواندن دادههای کوکی باشند (توصیه میشود)</translation> <translation id="2968755619301702150">بیننده گواهی</translation> <translation id="300526633675317032">این کار کل <ph name="SIZE_IN_KB" /> فضای ذخیرهسازی وبسایت را پاک میکند.</translation> +<translation id="301521992641321250">مسدودشده بهطور خودکار</translation> <translation id="3115898365077584848">نمایش دادن اطلاعات</translation> <translation id="3123473560110926937">در برخی سایتها مسدود میشود</translation> <translation id="3190152372525844641">مجوزهای Chrome را در <ph name="BEGIN_LINK" />تنظیمات Android <ph name="END_LINK" /> روشن کنید.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">همگامسازی پسزمینه</translation> <translation id="3822502789641063741">فضای ذخیره سایت پاک شود؟</translation> <translation id="385051799172605136">بازگشت</translation> +<translation id="3859306556332390985">جستجو به جلو</translation> <translation id="3955193568934677022">به سایتها اجازه داده شود محتوای محافظتشده پخش کنند (توصیه میشود)</translation> <translation id="3987993985790029246">کپی پیوند</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> از ؟</translation> <translation id="4002066346123236978">عنوان</translation> <translation id="4008040567710660924">کوکیها را برای سایت خاصی مجاز کنید.</translation> +<translation id="4046123991198612571">آهنگ بعدی</translation> <translation id="4165986682804962316">تنظیمات سایت</translation> <translation id="4226663524361240545">اعلانها ممکن است دستگاه را بلرزانند</translation> <translation id="4242533952199664413">باز کردن تنظیمات</translation> <translation id="4259722352634471385">پیمایش مسدود شده است: <ph name="URL" /></translation> <translation id="4278390842282768270">مجاز است</translation> +<translation id="429312253194641664">سایتی درحال پخش رسانه است</translation> <translation id="4433925000917964731">صفحه سادهشده را Google ارائه کرده است</translation> <translation id="4434045419905280838">پنجرههای بازشو و هدایتها</translation> <translation id="445467742685312942">به سایتها اجازه داده شود محتوای محافظتشده پخش کنند</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">لغو همه مجوزها برای دستگاه</translation> <translation id="4964199952259983386">برای اینکه به Chrome اجازه دهید از AR استفاده کند، دوربین را در <ph name="BEGIN_LINK" />تنظیمات Android<ph name="END_LINK" /> نیز روشن کنید.</translation> <translation id="497421865427891073">جلو رفتن</translation> +<translation id="4996978546172906250">اشتراکگذاری از طریق</translation> <translation id="5039804452771397117">اجازه دادن</translation> <translation id="5048398596102334565">مجاز بودن دسترسی سایتها به حسگرهای حرکتی (توصیه میشود)</translation> <translation id="5063480226653192405">کاربر </translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">پاک کردن</translation> <translation id="6697925417670533197">بارگیریهای فعال</translation> <translation id="6746124502594467657">انتقال به پایین</translation> +<translation id="6766622839693428701">برای بستن، تند به پایین بکشید.</translation> <translation id="6782111308708962316">جلوگیری از ذخیره کردن و خواندن دادههای کوکی توسط وبسایتهای شخص ثالث</translation> +<translation id="6790428901817661496">پخش</translation> <translation id="6818926723028410516">انتخاب موارد</translation> <translation id="6864395892908308021">این دستگاه نمیتواند NFC را بخواند</translation> <translation id="6910211073230771657">حذف شد</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">سایتی درحال استفاده از دوربینتان است</translation> <translation id="7817023149356982970">از سیستم این سایت خارج خواهید شد.</translation> <translation id="7828557259026017104">کوکیها فایلهایی هستند که توسط وبسایتهایی که بازدید میکنید ایجاد میشوند. سایتها برای بهخاطر سپردن اولویتهایتان از آنها استفاده میکنند. کوکیهای شخص ثالث را سایتهای دیگری ایجاد میکنند. برخی از محتواها مثل آگهیها یا تصاویر موجود در صفحه وبی که از آن دیدن میکنید، متعلق به این سایتها هستند.</translation> +<translation id="7835852323729233924">درحال پخش رسانه</translation> <translation id="7846076177841592234">لغو انتخاب</translation> <translation id="7846621471902887024">از سیستم همه سایتها خارج خواهید شد.</translation> <translation id="7882806643839505685">پخش صدا برای سایت خاصی مجاز شود.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">مطمئنید که میخواهید تمام دادههای محلی، شامل کوکیها را حذف کنید و تمام مجوزهای این وبسایت را بازنشانی کنید؟</translation> <translation id="8007176423574883786">برای این دستگاه غیرفعال شد</translation> <translation id="802154636333426148">بارگیری نشد</translation> +<translation id="8068648041423924542">انتخاب گواهی ممکن نیست.</translation> <translation id="8087000398470557479">این محتوا از <ph name="DOMAIN_NAME" /> است و توسط Google ارائه میشود.</translation> <translation id="8116925261070264013">صامتشده</translation> <translation id="8131740175452115882">تأیید</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">سایتی درحال استفاده از دوربین و میکروفونتان است</translation> <translation id="8380167699614421159">این سایتْ آگهیهای مزاحم یا گمراهکننده نشان میدهد</translation> <translation id="8394832520002899662">برای برگشتن به سایت ضربه بزنید</translation> +<translation id="8425213833346101688">تغییر</translation> +<translation id="8441146129660941386">جستجو به عقب</translation> <translation id="8447861592752582886">لغو مجوز دستگاه</translation> <translation id="8463851957836045671">سایت سریع است</translation> <translation id="851751545965956758">مسدود کردن سایتها برای اتصال به دستگاهها</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">کوکیها را برای سایت خاصی مسدود کنید.</translation> <translation id="8959122750345127698">پیمایش غیرقابل دسترسی است: <ph name="URL" /></translation> <translation id="9019902583201351841">مدیریت شده توسط والدین شما</translation> +<translation id="9074739597929991885">بلوتوث</translation> <translation id="945632385593298557">دسترسی به میکروفن</translation> <translation id="965817943346481315">اگر سایتْ آگهیهای مزاحم یا گمراهکننده نشان میدهد مسدود شود (توصیه میشود)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_fi.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_fi.xtb index 2d4229d3685..855df4d0b47 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_fi.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_fi.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Seuraava</translation> <translation id="1242008676835033345">Upotettu sivustolle <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Pysäytä</translation> +<translation id="1289742167380433257">Datan säästämiseksi Google on optimoinut tämän sivun kuvat.</translation> <translation id="129382876167171263">Sivustojen tallentamat tiedostot näkyvät tässä</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> – <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Sivusto <ph name="SITE_NAME" /> lisättiin.</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Kysy, saavatko sivustot luoda 3D-kartan ympäristöstäsi tai seurata kameran asentoa (suositus)</translation> <translation id="2212565012507486665">Salli evästeet</translation> <translation id="2289270750774289114">Kysy aina, kun sivusto pyytää lupaa löytää lähellä olevat Bluetooth-laitteet (suositus)</translation> +<translation id="2315043854645842844">Käyttöjärjestelmä ei tue palvelimen varmennevalintaa.</translation> <translation id="2359808026110333948">Jatka</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> Mt</translation> <translation id="2434158240863470628">Lataus valmis <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Kopioitu</translation> <translation id="2822354292072154809">Haluatko varmasti nollata kaikki sivuston käyttöoikeudet (<ph name="CHOSEN_OBJECT_NAME" />)?</translation> <translation id="2870560284913253234">Sivusto</translation> +<translation id="2874939134665556319">Edellinen kappale</translation> <translation id="2910701580606108292">Kysy, saavatko sivustot toistaa suojattua sisältöä</translation> <translation id="2913331724188855103">Salli sivustojen tallentaa ja lukea evästetietoja (suositus)</translation> <translation id="2968755619301702150">Varmennetiedot</translation> <translation id="300526633675317032">Tämä tyhjentää yhteensä <ph name="SIZE_IN_KB" /> tallennettuja sivustotietoja.</translation> +<translation id="301521992641321250">Estetty automaattisesti</translation> <translation id="3115898365077584848">Näytä tiedot</translation> <translation id="3123473560110926937">Estetty tietyillä sivustoilla</translation> <translation id="3190152372525844641">Ota käyttöoikeudet käyttöön Chromelle <ph name="BEGIN_LINK" />Android-asetuksissa<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Taustasynkronointi</translation> <translation id="3822502789641063741">Poistetaanko tiedot?</translation> <translation id="385051799172605136">Takaisin</translation> +<translation id="3859306556332390985">Kelaa eteenpäin</translation> <translation id="3955193568934677022">Salli sivustojen toistaa suojattua sisältöä (suositus)</translation> <translation id="3987993985790029246">Kopioi linkki</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">Nimi</translation> <translation id="4008040567710660924">Salli evästeet tietyllä sivustolla.</translation> +<translation id="4046123991198612571">Seuraava kappale</translation> <translation id="4165986682804962316">Sivustoasetukset</translation> <translation id="4226663524361240545">Laite voi väristä ilmoitusten yhteydessä.</translation> <translation id="4242533952199664413">Avaa asetukset</translation> <translation id="4259722352634471385">Kohde on estetty: <ph name="URL" /></translation> <translation id="4278390842282768270">Sallittu</translation> +<translation id="429312253194641664">Sivusto toistaa mediaa</translation> <translation id="4433925000917964731">Googlen tarjoama yksinkertaistettu sivu</translation> <translation id="4434045419905280838">Ponn.ikkunat ja uudelleenohjaus</translation> <translation id="445467742685312942">Salli sivustojen toistaa suojattua sisältöä</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Peru kaikki laitteen käyttöoikeudet</translation> <translation id="4964199952259983386">Laita kamera päälle myös <ph name="BEGIN_LINK" />Androidin asetuksista<ph name="END_LINK" />, jotta Chrome voi käyttää AR:ää.</translation> <translation id="497421865427891073">Siirry eteenpäin</translation> +<translation id="4996978546172906250">Jaa palvelussa:</translation> <translation id="5039804452771397117">Salli</translation> <translation id="5048398596102334565">Anna sivustojen käyttää liiketunnistimien lukemia (suositus)</translation> <translation id="5063480226653192405">Käyttö</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Tyhjennä</translation> <translation id="6697925417670533197">Aktiiviset lataukset</translation> <translation id="6746124502594467657">Siirrä alas</translation> +<translation id="6766622839693428701">Sulje pyyhkäisemällä alas.</translation> <translation id="6782111308708962316">Estä kolmannen osapuolen verkkosivustoja tallentamasta ja lukemasta evästetietoja</translation> +<translation id="6790428901817661496">Toista</translation> <translation id="6818926723028410516">Valitse kohteet</translation> <translation id="6864395892908308021">Tämä laite ei lue NFC-dataa</translation> <translation id="6910211073230771657">Poistettu</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Sivusto käyttää kameraasi</translation> <translation id="7817023149356982970">Sinut kirjataan ulos tältä sivustolta.</translation> <translation id="7828557259026017104">Evästeet ovat avaamiesi verkkosivustojen luomia tiedostoja. Niiden avulla sivustot muistavat valintasi. Kolmannen osapuolen evästeitä luovat muut sivustot. Nämä sivustot omistavat mainoksia, kuvia tai muita sisältöjä, joita käytetään avaamallasi sivulla.</translation> +<translation id="7835852323729233924">Toistetaan mediaa</translation> <translation id="7846076177841592234">Peruuta valinta</translation> <translation id="7846621471902887024">Sinut kirjataan ulos kaikilta sivustoilta.</translation> <translation id="7882806643839505685">Salli tietyn sivuston äänet.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Haluatko varmasti tyhjentää kaikki paikalliset tiedot, mukaan lukien evästeet, ja nollata kaikki tämän verkkosivuston käyttöluvat?</translation> <translation id="8007176423574883786">Ei käytössä tällä laitteella</translation> <translation id="802154636333426148">Lataus epäonnistui.</translation> +<translation id="8068648041423924542">Varmenteen valinta epäonnistui</translation> <translation id="8087000398470557479">Google on toimittanut tämän sisällön osoitteesta <ph name="DOMAIN_NAME" />.</translation> <translation id="8116925261070264013">Mykistetty</translation> <translation id="8131740175452115882">Vahvista</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Sivusto käyttää kameraasi ja mikrofoniasi</translation> <translation id="8380167699614421159">Tällä sivustolla on häiritseviä tai harhaanjohtavia mainoksia</translation> <translation id="8394832520002899662">Palaa sivustolle napauttamalla</translation> +<translation id="8425213833346101688">Vaihda</translation> +<translation id="8441146129660941386">Kelaa taaksepäin</translation> <translation id="8447861592752582886">Peruuta laitteen käyttöoikeus</translation> <translation id="8463851957836045671">Sivusto on nopea</translation> <translation id="851751545965956758">Estä sivustoja yhdistämästä laitteisiin</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Estä evästeet tietyltä sivustolta.</translation> <translation id="8959122750345127698">Kohde ei ole saatavilla: <ph name="URL" /></translation> <translation id="9019902583201351841">Vanhempiesi hallinnoima</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Mikrofonin käyttöoikeus</translation> <translation id="965817943346481315">Estä, jos sivusto näyttää häiritseviä tai harhaanjohtavia mainoksia (suositus)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_fil.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_fil.xtb index 618e33183a1..8399935a493 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_fil.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_fil.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Susunod</translation> <translation id="1242008676835033345">Naka-embed sa <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Stop</translation> +<translation id="1289742167380433257">Para makatipid ka ng data, na-optimize ng Google ang mga larawan ng page na ito.</translation> <translation id="129382876167171263">Lalabas dito ang mga file na na-save ng mga website</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> - <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Nadagdag na ang site ng <ph name="SITE_NAME" /></translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Magtanong bago payagan ang mga site na gumawa ng 3D na mapa ng iyong kapaligiran o subaybayan ang posisyon ng camera (inirerekomenda)</translation> <translation id="2212565012507486665">Payagan ang cookies</translation> <translation id="2289270750774289114">Magtanong kapag gusto ng isang site na tumuklas ng mga Bluetooth device na nasa malapit (inirerekomenda)</translation> +<translation id="2315043854645842844">Hindi sinusuportahan ng operating system ang pagpipilian ng certificate sa panig ng kliyente.</translation> <translation id="2359808026110333948">Magpatuloy</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">Tapos nang mag-download <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Kinopya</translation> <translation id="2822354292072154809">Sigurado ka bang gusto mong i-reset ang lahat ng pahintulot sa site para sa <ph name="CHOSEN_OBJECT_NAME" />?</translation> <translation id="2870560284913253234">Site</translation> +<translation id="2874939134665556319">Nakaraang track</translation> <translation id="2910701580606108292">Magtanong bago payagan ang mga site na mag-play ng pinoprotektahang content</translation> <translation id="2913331724188855103">Payagan ang mga site na mag-save at magbasa ng data ng cookie (inirerekomenda)</translation> <translation id="2968755619301702150">Viewer ng certificate</translation> <translation id="300526633675317032">Iki-clear nito ang lahat ng <ph name="SIZE_IN_KB" /> ng storage ng website.</translation> +<translation id="301521992641321250">Awtomatikong na-block</translation> <translation id="3115898365077584848">Ipakita ang Impormasyon</translation> <translation id="3123473560110926937">Naka-block sa ilang site</translation> <translation id="3190152372525844641">I-on ang mga pahintulot para sa Chrome sa <ph name="BEGIN_LINK" />Mga Setting ng Android<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Pag-sync sa background</translation> <translation id="3822502789641063741">I-clear ang storage ng site?</translation> <translation id="385051799172605136">Bumalik</translation> +<translation id="3859306556332390985">Maghanap nang pasulong</translation> <translation id="3955193568934677022">Pahintulutan ang mga site na mag-play ng pinoprotektahang content (inirerekomenda)</translation> <translation id="3987993985790029246">Kopyahin ang link</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">Pamagat</translation> <translation id="4008040567710660924">Payagan ang cookies para sa isang partikular na site.</translation> +<translation id="4046123991198612571">Susunod na track</translation> <translation id="4165986682804962316">Mga setting ng site</translation> <translation id="4226663524361240545">Maaaring mag-vibrate ang device dahil sa mga notification</translation> <translation id="4242533952199664413">Buksan ang mga setting</translation> <translation id="4259722352634471385">Naka-block ang navigation: <ph name="URL" /></translation> <translation id="4278390842282768270">Pinapayagan</translation> +<translation id="429312253194641664">May site na nagpe-play ng media</translation> <translation id="4433925000917964731">Hatid ng Google ang lite na page</translation> <translation id="4434045419905280838">Mga pop-up at pag-redirect</translation> <translation id="445467742685312942">Pahintulutan ang mga site na mag-play ng pinoprotektahang content</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Bawiin ang lahat ng pahintulot para sa device</translation> <translation id="4964199952259983386">Para payagan ang Chrome na gumamit ng AR, i-on din ang camera sa <ph name="BEGIN_LINK" />Mga Setting ng Android<ph name="END_LINK" />.</translation> <translation id="497421865427891073">Sumulong</translation> +<translation id="4996978546172906250">Ibahagi gamit ang</translation> <translation id="5039804452771397117">Payagan</translation> <translation id="5048398596102334565">Payagan ang mga site na i-access ang mga sensor ng paggalaw (inirerekomenda)</translation> <translation id="5063480226653192405">Paggamit</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">I-clear</translation> <translation id="6697925417670533197">Mga aktibong pag-download</translation> <translation id="6746124502594467657">Ibaba</translation> +<translation id="6766622839693428701">Mag-swipe pababa para isara.</translation> <translation id="6782111308708962316">Pigilan ang mga third-party na website na mag-save at magbasa ng data ng cookie</translation> +<translation id="6790428901817661496">I-play</translation> <translation id="6818926723028410516">Pumili ng mga item</translation> <translation id="6864395892908308021">Hindi nababasa ng device na ito ang NFC</translation> <translation id="6910211073230771657">Na-delete</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Ginagamit ng isang site ang iyong camera</translation> <translation id="7817023149356982970">Masa-sign out ka sa site na ito.</translation> <translation id="7828557259026017104">Ang cookies ay mga file na ginagawa ng mga website na binibisita mo. Ginagamit ng mga site ang mga ito para tandaan ang iyong mga kagustuhan. Ginagawa ng iba pang site ang third-party na cookies. Nagmamay-ari ang mga site na ito ng ilan sa content, gaya ng mga ad o larawan, na nakikita mo sa webpage na iyong binibisita.</translation> +<translation id="7835852323729233924">Nagpe-play ng media</translation> <translation id="7846076177841592234">Kanselahin ang pinili</translation> <translation id="7846621471902887024">Masa-sign out ka sa lahat ng site.</translation> <translation id="7882806643839505685">Payagan ang tunog para sa isang partikular na site.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Sigurado ka bang gusto mong i-clear ang lahat ng lokal na data, kasama ang cookies, at i-reset ang lahat ng pahintulot para sa website na ito?</translation> <translation id="8007176423574883786">Naka-off para sa device na ito</translation> <translation id="802154636333426148">Hindi na-download</translation> +<translation id="8068648041423924542">Hindi makapili ng certificate.</translation> <translation id="8087000398470557479">Ang content na ito ay mula sa <ph name="DOMAIN_NAME" />, na ipinadala ng Google.</translation> <translation id="8116925261070264013">Naka-mute</translation> <translation id="8131740175452115882">Kumpirmahin</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Ginagamit ng isang site ang iyong camera at mikropono</translation> <translation id="8380167699614421159">Nagpapakita ang site na ito ng mga nakakasagabal o nakakapanlinlang na ad</translation> <translation id="8394832520002899662">Mag-tap para bumalik sa site</translation> +<translation id="8425213833346101688">Baguhin</translation> +<translation id="8441146129660941386">Maghanap nang pabalik</translation> <translation id="8447861592752582886">Bawiin ang pahintulot ng device</translation> <translation id="8463851957836045671">Mabilis ang site</translation> <translation id="851751545965956758">I-block ang mga site sa pagkonekta sa mga device</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Mag-block ng cookies para sa isang partikular na site.</translation> <translation id="8959122750345127698">Hindi gumagana ang navigation: <ph name="URL" /></translation> <translation id="9019902583201351841">Pinamamahalaan ng iyong mga magulang</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">I-access ang iyong mikropono</translation> <translation id="965817943346481315">I-block kung nagpapakita ang site ng mga nakakasagabal o nakakapanlinlang na ad (inirerekomenda)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_fr-CA.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_fr-CA.xtb index 648c5f33af2..0a34e30200e 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_fr-CA.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_fr-CA.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Suivant</translation> <translation id="1242008676835033345">Intégré sur <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Arrêter</translation> +<translation id="1289742167380433257">Pour vous faire économiser les données, Google a optimisé les images de cette page.</translation> <translation id="129382876167171263">Les fichiers enregistrés par les sites Web s'affichent ici</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> : <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Le site <ph name="SITE_NAME" /> a été ajouté</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Demander avant d'autoriser les sites à créer une carte 3D de votre environnement ou à faire le suivi de la position de l'appareil photo (recommandé)</translation> <translation id="2212565012507486665">Autoriser les témoins</translation> <translation id="2289270750774289114">Demander quand un site souhaite rechercher les appareils Bluetooth à proximité (recommandé)</translation> +<translation id="2315043854645842844">La sélection du certificat client SSL n'est pas prise en charge par le système d'exploitation.</translation> <translation id="2359808026110333948">Continuer</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> Mo</translation> <translation id="2434158240863470628">Téléchargement terminé <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Copié</translation> <translation id="2822354292072154809">Voulez-vous vraiment réinitialiser toutes les autorisations de site pour <ph name="CHOSEN_OBJECT_NAME" />?</translation> <translation id="2870560284913253234">Site</translation> +<translation id="2874939134665556319">Chanson précédente</translation> <translation id="2910701580606108292">Demander avant d'autoriser les sites à lire du contenu protégé</translation> <translation id="2913331724188855103">Autoriser les sites à enregistrer et à lire les données des témoins (recommandé)</translation> <translation id="2968755619301702150">Lecteur de certificats</translation> <translation id="300526633675317032">Cette action entraînera la suppression de l'ensemble des <ph name="SIZE_IN_KB" /> d'espace de stockage des sites Web.</translation> +<translation id="301521992641321250">Bloquée automatiquement</translation> <translation id="3115898365077584848">Afficher les renseignements</translation> <translation id="3123473560110926937">Annonces bloquées sur certains sites</translation> <translation id="3190152372525844641">Activer les autorisations pour Chrome dans les <ph name="BEGIN_LINK" />paramètres Android<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Synchronisation en arrière-plan</translation> <translation id="3822502789641063741">Suppr. stock. des sites?</translation> <translation id="385051799172605136">Retour</translation> +<translation id="3859306556332390985">Rechercher vers l'avant</translation> <translation id="3955193568934677022">Autoriser les sites à lire le contenu protégé (recommandé)</translation> <translation id="3987993985790029246">Copier lien</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> <translation id="4002066346123236978">Titre</translation> <translation id="4008040567710660924">Autoriser les témoins pour un site en particulier.</translation> +<translation id="4046123991198612571">Chanson suivante</translation> <translation id="4165986682804962316">Paramètres du site</translation> <translation id="4226663524361240545">Les notifications peuvent faire vibrer l'appareil</translation> <translation id="4242533952199664413">Ouvrir les paramètres</translation> <translation id="4259722352634471385">Navigation bloquée : <ph name="URL" /></translation> <translation id="4278390842282768270">Autorisé</translation> +<translation id="429312253194641664">Un site lit du contenu multimédia</translation> <translation id="4433925000917964731">Page en version simplifiée fournie par Google</translation> <translation id="4434045419905280838">Fenêt. context. et redirections</translation> <translation id="445467742685312942">Autoriser les sites à lire du contenu protégé</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Révoquer toutes les autorisations pour l'appareil</translation> <translation id="4964199952259983386">Pour autoriser Chrome à utiliser la RA, activez aussi l'accès à l'appareil photo dans les <ph name="BEGIN_LINK" />paramètres Android<ph name="END_LINK" />.</translation> <translation id="497421865427891073">Avancer</translation> +<translation id="4996978546172906250">Partager par</translation> <translation id="5039804452771397117">Autoriser</translation> <translation id="5048398596102334565">Autoriser les sites à accéder à vos capteurs de mouvements (recommandé)</translation> <translation id="5063480226653192405">Utilisation</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Effacer</translation> <translation id="6697925417670533197">Téléchargements actifs</translation> <translation id="6746124502594467657">Déplacer vers le bas</translation> +<translation id="6766622839693428701">Glissez le doigt vers le bas pour fermer.</translation> <translation id="6782111308708962316">Empêcher les sites Web tiers d'enregistrer et de lire les données des témoins</translation> +<translation id="6790428901817661496">Jouer</translation> <translation id="6818926723028410516">Sélectionner des éléments</translation> <translation id="6864395892908308021">Cet appareil ne prend pas en charge la technologie NFC</translation> <translation id="6910211073230771657">Supprimé</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Un site utilise votre appareil photo</translation> <translation id="7817023149356982970">Vous serez déconnecté de ce site.</translation> <translation id="7828557259026017104">Les témoins sont des fichiers créés par les sites Web que vous visitez. Les sites les utilisent pour mémoriser vos préférences. Les témoins tiers sont ceux que créent d'autres sites. Ces sites possèdent certains types de contenu, comme des annonces et des images, que vous voyez sur les pages que vous visitez.</translation> +<translation id="7835852323729233924">Élém. multim. en cours de lecture</translation> <translation id="7846076177841592234">Annuler la sélection</translation> <translation id="7846621471902887024">Vous serez déconnecté de tous les sites.</translation> <translation id="7882806643839505685">Autorisez le son sur un site précis.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Voulez-vous vraiment effacer toutes les données locales de ce site Web, y compris les témoins, et réinitialiser toutes les autorisations pour ce site Web?</translation> <translation id="8007176423574883786">Désactivé pour cet appareil</translation> <translation id="802154636333426148">Échec du téléchargement</translation> +<translation id="8068648041423924542">Impossible de sélectionner le certificat.</translation> <translation id="8087000398470557479">Ce contenu provient de <ph name="DOMAIN_NAME" />, fourni par Google.</translation> <translation id="8116925261070264013">Désactivés</translation> <translation id="8131740175452115882">Confirmer</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Un site utilise votre appareil photo et votre microphone</translation> <translation id="8380167699614421159">Ce site diffuse des annonces intrusives ou trompeuses</translation> <translation id="8394832520002899662">Touchez pour revenir au site</translation> +<translation id="8425213833346101688">Modifier</translation> +<translation id="8441146129660941386">Rechercher vers l'arrière</translation> <translation id="8447861592752582886">Révoquer l'autorisation de l'appareil</translation> <translation id="8463851957836045671">Le site est rapide</translation> <translation id="851751545965956758">Empêcher les sites de se connecter à des appareils</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Bloquer les témoins pour un site en particulier.</translation> <translation id="8959122750345127698">Navigation inaccessible : <ph name="URL" /></translation> <translation id="9019902583201351841">Géré par tes parents</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Accès à votre microphone</translation> <translation id="965817943346481315">Bloquer si le site diffuse des annonces intrusives ou trompeuses (recommandé)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_fr.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_fr.xtb index d02c2416b92..fb2b937d601 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_fr.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_fr.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Suivant</translation> <translation id="1242008676835033345">Intégration sur <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Arrêter</translation> +<translation id="1289742167380433257">Pour sauvegarder vos données, les images de cette page ont été optimisées par Google.</translation> <translation id="129382876167171263">Les fichiers enregistrés par des sites Web sont répertoriés ici</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> - <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Site "<ph name="SITE_NAME" />" ajouté</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Vous demander votre avis avant d'autoriser les sites à créer un plan 3D de votre environnement ou à suivre la position de la caméra (recommandé)</translation> <translation id="2212565012507486665">Autoriser les cookies</translation> <translation id="2289270750774289114">Me demander lorsqu'un site souhaite accéder aux appareils Bluetooth se trouvant à proximité (recommandé)</translation> +<translation id="2315043854645842844">La sélection de certificat côté client n'est pas compatible avec le système d'exploitation.</translation> <translation id="2359808026110333948">Continuer</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> Mo</translation> <translation id="2434158240863470628">Téléchargement terminé <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Copié</translation> <translation id="2822354292072154809">Voulez-vous vraiment réinitialiser toutes les autorisations du site pour <ph name="CHOSEN_OBJECT_NAME" /> ?</translation> <translation id="2870560284913253234">Site</translation> +<translation id="2874939134665556319">Piste précédente</translation> <translation id="2910701580606108292">Demander avant d'autoriser les sites à lire les contenus protégés</translation> <translation id="2913331724188855103">Autoriser les sites à enregistrer et à lire les données des cookies (recommandé)</translation> <translation id="2968755619301702150">Lecteur de certificat</translation> <translation id="300526633675317032">Cette action aura pour effet de libérer l'espace de stockage utilisé pour les données de site (<ph name="SIZE_IN_KB" />).</translation> +<translation id="301521992641321250">Bloquée automatiquement</translation> <translation id="3115898365077584848">Afficher les informations</translation> <translation id="3123473560110926937">Bloqué sur certains sites</translation> <translation id="3190152372525844641">Activer les autorisations pour Chrome dans les <ph name="BEGIN_LINK" />paramètres Android<ph name="END_LINK" /></translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Synchronisation en arrière-plan</translation> <translation id="3822502789641063741">Suppr. données de site ?</translation> <translation id="385051799172605136">Retour</translation> +<translation id="3859306556332390985">Avance rapide</translation> <translation id="3955193568934677022">Autoriser les sites à lire les contenus protégés (recommandé)</translation> <translation id="3987993985790029246">Copier lien</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/ ?</translation> <translation id="4002066346123236978">Titre</translation> <translation id="4008040567710660924">Autorisez les cookies pour un site spécifique.</translation> +<translation id="4046123991198612571">Piste suivante</translation> <translation id="4165986682804962316">Paramètres de site</translation> <translation id="4226663524361240545">L'appareil vibrera en cas de notifications.</translation> <translation id="4242533952199664413">Ouvrir les paramètres</translation> <translation id="4259722352634471385">La navigation sur <ph name="URL" /> est bloquée.</translation> <translation id="4278390842282768270">Autorisé</translation> +<translation id="429312253194641664">Un site est en train de lire un contenu multimédia</translation> <translation id="4433925000917964731">Page simplifiée fournie par Google</translation> <translation id="4434045419905280838">Pop-up et redirections</translation> <translation id="445467742685312942">Autoriser les sites à lire les contenus protégés</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Révoquer toutes les autorisations de l'appareil</translation> <translation id="4964199952259983386">Pour autoriser Chrome à utiliser la RA, activez également l'appareil photo dans les <ph name="BEGIN_LINK" />paramètres Android<ph name="END_LINK" />.</translation> <translation id="497421865427891073">Avancer</translation> +<translation id="4996978546172906250">Partager via</translation> <translation id="5039804452771397117">Autoriser</translation> <translation id="5048398596102334565">Autoriser les sites à accéder à vos capteurs de mouvement (recommandé)</translation> <translation id="5063480226653192405">Utilisation</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Effacer</translation> <translation id="6697925417670533197">Téléchargements actifs</translation> <translation id="6746124502594467657">Descendre</translation> +<translation id="6766622839693428701">Balayez l'écran vers le bas pour fermer la feuille.</translation> <translation id="6782111308708962316">Empêcher les sites Web tiers d'enregistrer et de lire les données des cookies</translation> +<translation id="6790428901817661496">Lire</translation> <translation id="6818926723028410516">Sélectionner des éléments</translation> <translation id="6864395892908308021">Lecture NFC impossible sur cet appareil</translation> <translation id="6910211073230771657">Supprimé</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Un site utilise actuellement votre appareil photo</translation> <translation id="7817023149356982970">Vous allez être déconnecté de ce site.</translation> <translation id="7828557259026017104">Les cookies sont des fichiers créés par les sites Web que vous consultez. Les sites les utilisent pour mémoriser vos préférences. Les cookies tiers sont créés par d'autres sites, lesquels possèdent une partie du contenu, comme les annonces ou les images, que vous voyez sur la page Web que vous consultez.</translation> +<translation id="7835852323729233924">Contenu en cours de lecture</translation> <translation id="7846076177841592234">Annuler la sélection</translation> <translation id="7846621471902887024">Vous allez être déconnecté de tous les sites.</translation> <translation id="7882806643839505685">Autorisez le son pour un site spécifique.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Voulez-vous vraiment effacer toutes les données locales, y compris les cookies, et réinitialiser toutes les autorisations pour ce site Web ?</translation> <translation id="8007176423574883786">Désactivée pour cet appareil</translation> <translation id="802154636333426148">Échec du téléchargement</translation> +<translation id="8068648041423924542">Impossible de sélectionner le certificat</translation> <translation id="8087000398470557479">Ce contenu est issu de <ph name="DOMAIN_NAME" />. Il est diffusé par Google.</translation> <translation id="8116925261070264013">Son coupé</translation> <translation id="8131740175452115882">Confirmer</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Un site utilise votre appareil photo et votre micro</translation> <translation id="8380167699614421159">Ce site affiche des annonces intrusives ou trompeuses</translation> <translation id="8394832520002899662">Appuyez pour revenir au site</translation> +<translation id="8425213833346101688">Modifier</translation> +<translation id="8441146129660941386">Retour rapide</translation> <translation id="8447861592752582886">Révoquer l'autorisation d'accès à l'appareil</translation> <translation id="8463851957836045671">Le site est rapide</translation> <translation id="851751545965956758">Interdire à tous les sites de se connecter à des appareils</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Bloquez les cookies pour un site spécifique.</translation> <translation id="8959122750345127698">Impossible d'accéder à <ph name="URL" />.</translation> <translation id="9019902583201351841">Géré par tes parents</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Accéder à votre micro</translation> <translation id="965817943346481315">Bloquer si le site affiche des annonces intrusives ou trompeuses (recommandé)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_gl.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_gl.xtb index ad0656493e1..67a5521ac27 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_gl.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_gl.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Seguinte</translation> <translation id="1242008676835033345">Cookie inserida en <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Deter</translation> +<translation id="1289742167380433257">Para gardar os teus datos, Google optimizou as imaxes desta páxina.</translation> <translation id="129382876167171263">Os ficheiros gardados polos sitios web aparecen aquí</translation> <translation id="1364532808393826295"><ph name="APP_NAME" />: <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Engadiuse o sitio <ph name="SITE_NAME" /></translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Preguntar antes de permitir que os sitios creen un mapa 3D do que te rodea e fagan un seguimento da posición da cámara (recomendado)</translation> <translation id="2212565012507486665">Permitir uso de cookies</translation> <translation id="2289270750774289114">Preguntar cando un sitio web queira detectar dispositivos Bluetooth próximos (recomendado)</translation> +<translation id="2315043854645842844">A selección do certificado do cliente non é compatible co sistema operativo.</translation> <translation id="2359808026110333948">Continuar</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">Completouse a descarga <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Copiada</translation> <translation id="2822354292072154809">Seguro que queres restablecer todos os permisos do sitio <ph name="CHOSEN_OBJECT_NAME" />?</translation> <translation id="2870560284913253234">Sitio</translation> +<translation id="2874939134665556319">Pista anterior</translation> <translation id="2910701580606108292">Preguntar antes de permitir que os sitios reproduzan contido protexido</translation> <translation id="2913331724188855103">Permitir que os sitios garden e lean datos de cookies (recomendado)</translation> <translation id="2968755619301702150">Visor de certificados</translation> <translation id="300526633675317032">Eliminaranse os <ph name="SIZE_IN_KB" /> de almacenamento do sitio web.</translation> +<translation id="301521992641321250">Bloqueado automaticamente</translation> <translation id="3115898365077584848">Mostrar información</translation> <translation id="3123473560110926937">Anuncios bloqueados nalgúns sitios</translation> <translation id="3190152372525844641">Activa os permisos para Chrome na <ph name="BEGIN_LINK" />Configuración de Android<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Sincronización en segundo plano</translation> <translation id="3822502789641063741">Borrar datos do sitio?</translation> <translation id="385051799172605136">Atrás</translation> +<translation id="3859306556332390985">Buscar cara adiante</translation> <translation id="3955193568934677022">Permitir que os sitios reproduzan contido protexido (recomendado)</translation> <translation id="3987993985790029246">Copiar ligazón</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> <translation id="4002066346123236978">Título</translation> <translation id="4008040567710660924">Permite cookies para un sitio específico.</translation> +<translation id="4046123991198612571">Pista seguinte</translation> <translation id="4165986682804962316">Configuración do sitio</translation> <translation id="4226663524361240545">O dispositivo pode vibrar ao recibir notificacións</translation> <translation id="4242533952199664413">Abrir configuración</translation> <translation id="4259722352634471385">A navegación está bloqueada: <ph name="URL" /></translation> <translation id="4278390842282768270">Permitida</translation> +<translation id="429312253194641664">Un sitio está reproducindo contido multimedia</translation> <translation id="4433925000917964731">Páxina en modo básico ofrecida por Google.</translation> <translation id="4434045419905280838">Ventás emerxentes e redireccións</translation> <translation id="445467742685312942">Permitir que os sitios reproduzan contido protexido</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Revogar todos os permisos do dispositivo</translation> <translation id="4964199952259983386">Para permitir que Chrome utilice a realidade aumentada, tamén debes activar a cámara na sección <ph name="BEGIN_LINK" />Configuración de Android<ph name="END_LINK" />.</translation> <translation id="497421865427891073">Avanzar</translation> +<translation id="4996978546172906250">Compartir a través de</translation> <translation id="5039804452771397117">Permitir</translation> <translation id="5048398596102334565">Permite aos sitios acceder aos teus sensores de movemento (recomendado)</translation> <translation id="5063480226653192405">Uso</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Borrar</translation> <translation id="6697925417670533197">Descargas activas</translation> <translation id="6746124502594467657">Mover cara abaixo</translation> +<translation id="6766622839693428701">Pasa o dedo cara abaixo para pechar o panel inferior.</translation> <translation id="6782111308708962316">Evitar que sitios web de terceiros garden e lean datos de cookies</translation> +<translation id="6790428901817661496">Reproducir</translation> <translation id="6818926723028410516">Selecciona elementos</translation> <translation id="6864395892908308021">Este dispositivo non pode ler NFC</translation> <translation id="6910211073230771657">Eliminado</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Un sitio está utilizando a cámara</translation> <translation id="7817023149356982970">Pecharase a túa sesión neste sitio.</translation> <translation id="7828557259026017104">As cookies son ficheiros creados polos sitios web que visitas. Os sitios utilízanas para lembrar as túas preferencias. As de terceiros son as que crean outros sitios. Parte do contido que ves na páxina web que visitas, como anuncios ou imaxes, pertence a esoutros sitios.</translation> +<translation id="7835852323729233924">Reproducindo contido multimedia</translation> <translation id="7846076177841592234">Cancelar selección</translation> <translation id="7846621471902887024">Pecharase a túa sesión en todos os sitios.</translation> <translation id="7882806643839505685">Permite o son dun sitio específico.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Estás seguro de que queres borrar todos os datos locais, incluídas as cookies, e restablecer todos os permisos para este sitio web?</translation> <translation id="8007176423574883786">Desactivada para este dispositivo</translation> <translation id="802154636333426148">Produciuse un erro na descarga</translation> +<translation id="8068648041423924542">Non se pode seleccionar o certificado.</translation> <translation id="8087000398470557479">Este contido procede de <ph name="DOMAIN_NAME" />, ofrecido por Google.</translation> <translation id="8116925261070264013">Silenciados</translation> <translation id="8131740175452115882">Confirmar</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Un sitio está utilizando a cámara e o micrófono</translation> <translation id="8380167699614421159">Este sitio mostra anuncios intrusivos ou enganosos</translation> <translation id="8394832520002899662">Toca para volver ao sitio</translation> +<translation id="8425213833346101688">Cambiar</translation> +<translation id="8441146129660941386">Buscar cara atrás</translation> <translation id="8447861592752582886">Revoga o permiso do dispositivo</translation> <translation id="8463851957836045671">O sitio é rápido</translation> <translation id="851751545965956758">Non permitir que os sitios se conecten aos dispositivos</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Bloquea cookies para un sitio específico.</translation> <translation id="8959122750345127698">A navegación é inaccesible: <ph name="URL" /></translation> <translation id="9019902583201351841">Xestionado por teus pais</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Acceso ao teu micrófono</translation> <translation id="965817943346481315">Bloquear se o sitio mostra anuncios enganosos ou intrusivos (recomendado)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_gu.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_gu.xtb index 0cff9eb110c..a3e8767f884 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_gu.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_gu.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">આગલું</translation> <translation id="1242008676835033345"><ph name="WEBSITE_URL" /> પર શામેલ કર્યું</translation> <translation id="1272079795634619415">રોકો</translation> +<translation id="1289742167380433257">તમારો ડેટા બચાવવા માટે, આ પેજની છબીઓને Google દ્વારા ઑપ્ટિમાઇઝ કરવામાં આવી છે.</translation> <translation id="129382876167171263">વેબસાઇટ દ્વારા સાચવવામાં આવેલી ફાઇલો અહી દેખાશે</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> - <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">સાઈટ <ph name="SITE_NAME" /> ઉમેરવામાં આવી</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">કોઈ સાઇટને તમારી આજુબાજુનો 3D નકશો બનાવતા અથવા કૅમેરાની સ્થિતિને ટ્રૅક કરવાની મંજૂરી આપતા પહેલાં પૂછો (સુઝાવ આપીએ છીએ)</translation> <translation id="2212565012507486665">કુકીને મંજૂરી આપો</translation> <translation id="2289270750774289114">જ્યારે કોઈ સાઇટ નજીકના બ્લૂટૂથ ડિવાઇસને શોધવા માગે ત્યારે પૂછો (સુઝાવ આપેલ)</translation> +<translation id="2315043854645842844">ઓપરેટિંગ સિસ્ટમ દ્વારા ક્લાઇન્ટ તરફની પ્રમાણપત્ર પસંદગી સપોર્ટ કરતી નથી.</translation> <translation id="2359808026110333948">આગળ વધો</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">ડાઉનલોડ પૂર્ણ <ph name="SEPARATOR" /><ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">કૉપિ કર્યું</translation> <translation id="2822354292072154809">શું તમે ખરેખર <ph name="CHOSEN_OBJECT_NAME" />ની બધી સાઇટ પસંદગીઓને રીસેટ કરવા માગો છે?</translation> <translation id="2870560284913253234">સાઇટ</translation> +<translation id="2874939134665556319">પાછલું ટ્રૅક</translation> <translation id="2910701580606108292">સાઇટને સંરક્ષિત કન્ટેન્ટ ચલાવવાની મંજૂરી આપતા પહેલાંં પૂછો</translation> <translation id="2913331724188855103">સાઇટને કૂકી ડેટા સાચવવા અને વાંચવાની મંજૂરી આપો (ભલામણ કરેલ)</translation> <translation id="2968755619301702150">પ્રમાણપત્ર દર્શક</translation> <translation id="300526633675317032">આ <ph name="SIZE_IN_KB" /> નું બધું વેબસાઇટ સ્ટોરેજ સાફ કરશે.</translation> +<translation id="301521992641321250">આપમેળે અવરોધિત</translation> <translation id="3115898365077584848">માહિતી બતાવો</translation> <translation id="3123473560110926937">કેટલીક સાઇટ પર બ્લૉક કરેલ</translation> <translation id="3190152372525844641"><ph name="BEGIN_LINK" />Android સેટિંગ્સ<ph name="END_LINK" />માં Chrome માટે પરવાનગીઓ ચાલુ કરો.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">પૃષ્ઠભૂમિ સમન્વયન</translation> <translation id="3822502789641063741">સાઇટ સ્ટોરેજ સાફ કરીએ?</translation> <translation id="385051799172605136">પાછળ</translation> +<translation id="3859306556332390985">આગળ કરો</translation> <translation id="3955193568934677022">સાઇટને સંરક્ષિત કન્ટેન્ટ ચલાવવાની મંજૂરી આપો (ભલામણ કરેલ)</translation> <translation id="3987993985790029246">લિંક કૉપિ કરો</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">શીર્ષક</translation> <translation id="4008040567710660924">કોઈ ચોક્કસ સાઇટ માટે કુકીને મંજૂરી આપો.</translation> +<translation id="4046123991198612571">આગલો ટ્રૅક</translation> <translation id="4165986682804962316">સાઇટ સેટિંગ્સ</translation> <translation id="4226663524361240545">સૂચનાઓ ઉપકરણને વાઇબ્રેટ કરી શકે છે</translation> <translation id="4242533952199664413">સેટિંગ્સ ખોલો</translation> <translation id="4259722352634471385">નેવિગેશન અવરોધિત છે: <ph name="URL" /></translation> <translation id="4278390842282768270">મંજૂર</translation> +<translation id="429312253194641664">સાઇટ મીડિયા ચલાવી રહી છે</translation> <translation id="4433925000917964731">Google દ્વારા પૂરું પાડવામાં આવેલું લાઇટ વર્ઝનનું પેજ</translation> <translation id="4434045419905280838">પૉપ-અપ અને રીડાયરેક્ટ</translation> <translation id="445467742685312942">સાઇટને સંરક્ષિત કન્ટેન્ટ ચલાવવાની મંજૂરી આપો</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">ડિવાઇસ માટેની બધી પરવાનગીઓને રદબાતલ કરો</translation> <translation id="4964199952259983386">Chromeને ARનો વપરાશ કરવા દેવા માટે, <ph name="BEGIN_LINK" />Android સેટિંગ<ph name="END_LINK" />માંથી કૅમેરા પણ ચાલુ કરો.</translation> <translation id="497421865427891073">આગળ જાઓ</translation> +<translation id="4996978546172906250">આનાથી શેર કરો</translation> <translation id="5039804452771397117">મંજૂરી આપો</translation> <translation id="5048398596102334565">સાઇટને મોશન સેન્સરના ઍક્સેસની મંજૂરી આપો (સુઝાવ આપેલ)</translation> <translation id="5063480226653192405">ઉપયોગ</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">સાફ કરો</translation> <translation id="6697925417670533197">ડાઉનલોડ કરવાનું સક્રિય કરો</translation> <translation id="6746124502594467657">નીચે ખસેડો</translation> +<translation id="6766622839693428701">બંધ કરવા માટે નીચેની તરફ સ્વાઇપ કરો.</translation> <translation id="6782111308708962316">તૃતીય-પક્ષ વેબસાઇટને કુકી ડેટા સાચવવા અને વાંચવાથી અટકાવો</translation> +<translation id="6790428901817661496">ચલાવો</translation> <translation id="6818926723028410516">આઇટમ પસંદ કરો</translation> <translation id="6864395892908308021">આ ડિવાઇસ NFC વાંચી શકતું નથી</translation> <translation id="6910211073230771657">કાઢી નાખ્યું</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">કોઈ સાઇટ તમારા કૅમેરાનો ઉપયોગ કરી રહી છે</translation> <translation id="7817023149356982970">આ સાઇટમાંથી તમને સાઇન આઉટ કરવામાં આવશે.</translation> <translation id="7828557259026017104">કુકી એ તમે મુલાકાત લો છો તે વેબસાઇટ દ્વારા બનાવવામાં આવેલી ફાઇલો છે. સાઇટ તેનો ઉપયોગ તમારી પસંદગીઓને યાદ રાખવા માટે કરે છે. ત્રીજા પક્ષની કુકી અન્ય સાઇટ દ્વારા બનાવવામાં આવે છે. અમુક પ્રકારનું કન્ટેન્ટ આ સાઇટની માલિકીનું હોય છે, જેમ કે તમે મુલાકાત લો છો તે વેેબપેજ પર તમે જોયેલી જાહેરાતો કે છબીઓ.</translation> +<translation id="7835852323729233924">મીડિયા ચલાવી રહ્યાં છીએ</translation> <translation id="7846076177841592234">પસંદગી રદ કરો</translation> <translation id="7846621471902887024">તમે બધી સાઇટમાં સાઇન આઉટ કરવામાં આવશે.</translation> <translation id="7882806643839505685">કોઈ એક ચોક્કસ સાઇટ માટે અવાજ ચલાવવાની મંજૂરી આપો.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">શું તમે ખરેખર કૂકીઝ સહિત આ વેબસાઇટ માટેનો બધો ડેટા સાફ કરી અને આ વેબસાઇટ માટેની બધી પરવાનગીઓ ફરીથી સેટ કરવા માગો છો?</translation> <translation id="8007176423574883786">આ ઉપકરણ માટે બંધ કર્યું</translation> <translation id="802154636333426148">ડાઉનલોડ નિષ્ફળ થયું</translation> +<translation id="8068648041423924542">પ્રમાણપત્ર પસંદ કરવામાં અસમર્થ.</translation> <translation id="8087000398470557479">આ કન્ટેન્ટ <ph name="DOMAIN_NAME" /> માંથી, Google દ્વારા વિતરિત કરેલ છે.</translation> <translation id="8116925261070264013">મ્યૂટ કરેલ</translation> <translation id="8131740175452115882">પુષ્ટિ કરો</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">કોઈ સાઇટ તમારા કૅમેરા અને માઇક્રોફોનનો ઉપયોગ કરી રહી છે</translation> <translation id="8380167699614421159">આ સાઇટ ઘૃણાસ્પદ અથવા ભ્રામક જાહેરાતો બતાવે છે</translation> <translation id="8394832520002899662">સાઇટ પર પાછા ફરવા માટે, ટૅપ કરો</translation> +<translation id="8425213833346101688">બદલો</translation> +<translation id="8441146129660941386">પાછળ કરો</translation> <translation id="8447861592752582886">ઉપકરણની પરવાનગી રદબાતલ કરો</translation> <translation id="8463851957836045671">સાઇટ ઝડપી છે</translation> <translation id="851751545965956758">સાઇટને ઉપકરણો સાથે કનેક્ટ થવાથી બ્લૉક કરો</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">કોઈ ચોક્કસ સાઇટ માટે કુકીને બ્લૉક કરો.</translation> <translation id="8959122750345127698">નેવિગેશન બિનપહોંચ યોગ્ય છે: <ph name="URL" /></translation> <translation id="9019902583201351841">તમારા માતાપિતા દ્વારા સંચાલિત</translation> +<translation id="9074739597929991885">બ્લૂટૂથ</translation> <translation id="945632385593298557">તમારા માઇક્રોફોનની ઍક્સેસ</translation> <translation id="965817943346481315">જો સાઇટ ઘૃણાસ્પદ અથવા ભ્રામક જાહેરાતો બતાવતી હોય, તો બ્લૉક કરો (ભલામણ કરેલ)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_hi.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_hi.xtb index 27fe6fe8b7e..edc7c1b2cd1 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_hi.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_hi.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">अगला</translation> <translation id="1242008676835033345"><ph name="WEBSITE_URL" /> पर एम्बेड किया गया</translation> <translation id="1272079795634619415">रोकें</translation> +<translation id="1289742167380433257">आपका डेटा बचाने के लिए, Google ने इस पेज की इमेज ऑप्टमाइज़ कर दी हैं.</translation> <translation id="129382876167171263">यहां वे फ़ाइलें दिखाई देती हैं जिन्हें वेबसाइटें सेव करती हैं</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> - <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676"><ph name="SITE_NAME" /> साइट जोड़ी गई</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">किसी साइट को आपके आस-पास की जगह का 3D मैप बनाने या कैमरे की स्थिति ट्रैक करने की अनुमति देने से पहले पूछें (सुझाया गया)</translation> <translation id="2212565012507486665">कुकी की अनुमति दें</translation> <translation id="2289270750774289114">जब कोई साइट आस-पास के ब्लूटूथ डिवाइस को खोजना चाहे, तो इसके लिए पूछें (सुझाया गया)</translation> +<translation id="2315043854645842844">क्लाइंट-साइड प्रमाणपत्र चुनना ऑपरेटिंग सिस्टम से नहीं किया जा सकता है.</translation> <translation id="2359808026110333948">जारी रखें</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> एमबी</translation> <translation id="2434158240863470628">डाउनलोड हो गया <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">कॉपी किया गया</translation> <translation id="2822354292072154809">क्या आप वाकई <ph name="CHOSEN_OBJECT_NAME" /> की सभी साइट अनुमतियां रीसेट करना चाहते हैं?</translation> <translation id="2870560284913253234">साइट</translation> +<translation id="2874939134665556319">पिछला ट्रैक</translation> <translation id="2910701580606108292">साइटों को सुरक्षित सामग्री चलाने की अनुमति देने से पहले पूछें</translation> <translation id="2913331724188855103">साइटों को कुकी डेटा सेव करने और पढ़ने की अनुमति दें (सुझाए गए)</translation> <translation id="2968755619301702150">प्रमाणपत्र व्यूअर</translation> <translation id="300526633675317032">इससे वेबसाइट की पूरी <ph name="SIZE_IN_KB" /> मेमोरी साफ़ हो जाएगी.</translation> +<translation id="301521992641321250">ऑटोमैटिक रूप से ब्लॉक है</translation> <translation id="3115898365077584848">जानकारी दिखाएं</translation> <translation id="3123473560110926937">कुछ साइटों पर ब्लॉक किए गए हैं</translation> <translation id="3190152372525844641"><ph name="BEGIN_LINK" />Android सेटिंग<ph name="END_LINK" /> में Chrome के लिए अनुमतियां चालू करें.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">बैकग्राउंड सिंक</translation> <translation id="3822502789641063741">क्या आप साइट मेमोरी खाली करना चाहते हैं?</translation> <translation id="385051799172605136">वापस जाएं</translation> +<translation id="3859306556332390985">आगे जाएं</translation> <translation id="3955193568934677022">साइटों को सुरक्षित सामग्री चलाने दें (हम इस सेटिंग को चालू रखने का सुझाव देते हैं)</translation> <translation id="3987993985790029246">लिंक की प्रति बनाएं</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">शीर्षक</translation> <translation id="4008040567710660924">किसी खास साइट के लिए कुकी की मंज़ूरी दें.</translation> +<translation id="4046123991198612571">अगला ट्रैक</translation> <translation id="4165986682804962316">साइट सेटिंग</translation> <translation id="4226663524361240545">नोटिफ़िकेशन से डिवाइस में कंपन हो सकता है</translation> <translation id="4242533952199664413">सेटिंग खोलें</translation> <translation id="4259722352634471385">मार्गदर्शक अवरोधित है: <ph name="URL" /></translation> <translation id="4278390842282768270">अनुमति है</translation> +<translation id="429312253194641664">किसी साइट पर मीडिया चल रहा है</translation> <translation id="4433925000917964731">लाइट पेज Google ने मुहैया कराया है</translation> <translation id="4434045419905280838">पॉप-अप और रीडायरेक्ट</translation> <translation id="445467742685312942">साइटों को सभी सुरक्षित सामग्री चलाने दें</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">डिवाइस की सभी अनुमतियां निरस्त करें</translation> <translation id="4964199952259983386">Chrome को एआर (ऑगमेंटेड रिएलिटी) का इस्तेमाल करने देने के लिए, <ph name="BEGIN_LINK" />Android सेटिंग<ph name="END_LINK" /> में जाकर कैमरा भी चालू कर दें.</translation> <translation id="497421865427891073">आगे जाएं</translation> +<translation id="4996978546172906250">इससे शेयर करें</translation> <translation id="5039804452771397117">अनुमति दें</translation> <translation id="5048398596102334565">साइटों को मोशन सेंसर ऐक्सेस करने दें (सुझाया गया)</translation> <translation id="5063480226653192405">उपयोग</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">साफ़ करें</translation> <translation id="6697925417670533197">डाउनलोड हो रहे हैं</translation> <translation id="6746124502594467657">नीचे ले जाएं</translation> +<translation id="6766622839693428701">बंद करने के लिए नीचे स्वाइप करें.</translation> <translation id="6782111308708962316">तृतीय पक्ष वेबसाइट को कुकी डेटा सहेजने और पढ़ने से रोकें</translation> +<translation id="6790428901817661496">चलाएं</translation> <translation id="6818926723028410516">आइटम चुनें</translation> <translation id="6864395892908308021">इस डिवाइस के साथ NFC काम नहीं कर सकता</translation> <translation id="6910211073230771657">हटाया गया</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">कोई साइट आपका कैमरा इस्तेमाल कर रही है</translation> <translation id="7817023149356982970">आप इस साइट से साइन आउट हो जाएंगे.</translation> <translation id="7828557259026017104">आप जिन वेबसाइटों पर जाते हैं उनकी बनाई फ़ाइलें कुकी कहलाती हैं. आपकी प्राथमिकताओं को याद रखने के लिए, साइटें उनका इस्तेमाल करती हैं. अन्य साइटें, तीसरे पक्ष की कुकी बनाती हैं. इन साइटों पर विज्ञापन या इमेज जैसी कुछ सामग्री होती हैं. ये उस वेबपेज पर दिखती है जिस पर आप जाते हैं.</translation> +<translation id="7835852323729233924">चलाया जा रहा मीडिया</translation> <translation id="7846076177841592234">चुना गया हटाएं</translation> <translation id="7846621471902887024">आप सभी साइटों से साइन आउट हो जाएंगे.</translation> <translation id="7882806643839505685">किसी खास साइट के लिए आवाज़ की अनुमति दें.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">क्या आप वाकई कुकी सहित इस वेबसाइट का सभी स्थानीय डेटा साफ़ करना और इसकी सभी अनुमतियों को रीसेट करना चाहते हैं?</translation> <translation id="8007176423574883786">इस डिवाइस के लिए बंद कर दिया गया है</translation> <translation id="802154636333426148">डाउनलोड विफल रहा</translation> +<translation id="8068648041423924542">प्रमाणपत्र चुनने में असमर्थ.</translation> <translation id="8087000398470557479">यह सामग्री <ph name="DOMAIN_NAME" /> की है जिसे Google के द्वारा वितरित किया गया है.</translation> <translation id="8116925261070264013">आवाज़ बंद की गई</translation> <translation id="8131740175452115882">पुष्टि करें</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">कोई साइट आपके कैमरे और माइक्रोफ़ोन का इस्तेमाल कर रही है</translation> <translation id="8380167699614421159">इस साइट में तंग करने वाले या गुमराह करने वाले विज्ञापन दिखाई देते हैं</translation> <translation id="8394832520002899662">साइट पर वापस जाने के लिए टैप करें</translation> +<translation id="8425213833346101688">बदलें</translation> +<translation id="8441146129660941386">पीछे जाएं</translation> <translation id="8447861592752582886">डिवाइस अनुमति निरस्त करें</translation> <translation id="8463851957836045671">साइट तेज़ी से लोड होती है</translation> <translation id="851751545965956758">साइटों को डिवाइस से कनेक्ट होने से रोकें</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">किसी खास साइट के लिए कुकी ब्लॉक करें.</translation> <translation id="8959122750345127698">मार्गदर्शक तक नहीं पहुंचा जा सकता: <ph name="URL" /></translation> <translation id="9019902583201351841">आपके अभिभावकों द्वारा प्रबंधित</translation> +<translation id="9074739597929991885">ब्लूटूथ</translation> <translation id="945632385593298557">अपना माइक्रोफ़ोन एक्सेस करें</translation> <translation id="965817943346481315">अगर साइट तंग करने वाले या गुमराह करने वाले विज्ञापन दिखाई देते हैं, तो उन्हें ब्लॉक करें (सुझाव)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_hr.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_hr.xtb index adbb13cf623..86bf11620c0 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_hr.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_hr.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Dalje</translation> <translation id="1242008676835033345">Ugrađeno na <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Zaustavi</translation> +<translation id="1289742167380433257">Google je optimizirao slike na ovoj stranici radi uštede vaših podataka.</translation> <translation id="129382876167171263">Ovdje se prikazuju datoteke koje su spremile web-lokacije</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> – <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Dodana je web-lokacija <ph name="SITE_NAME" /></translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Prikaži upit prije omogućivanja web-lokacijama da izrađuju 3D kartu vašeg okruženja i prate položaj kamere (preporučeno)</translation> <translation id="2212565012507486665">Dopusti kolačiće</translation> <translation id="2289270750774289114">Prikaži upit kad web-lokacija želi tražiti Bluetooth uređaje u blizini (preporučeno)</translation> +<translation id="2315043854645842844">Operativni sustav ne podržava odabir klijentskog certifikata.</translation> <translation id="2359808026110333948">Nastavi</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">Preuzimanje je dovršeno: <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Kopirano</translation> <translation id="2822354292072154809">Jeste li sigurni da želite poništiti sva dopuštenja za aplikaciju <ph name="CHOSEN_OBJECT_NAME" />?</translation> <translation id="2870560284913253234">Web lokacija</translation> +<translation id="2874939134665556319">Prethodna pjesma</translation> <translation id="2910701580606108292">Web-lokacije moraju tražiti dopuštenje za reprodukciju zaštićenog sadržaja</translation> <translation id="2913331724188855103">Dopusti web-lokacijama da spremaju i čitaju podatke kolačića (preporučeno)</translation> <translation id="2968755619301702150">Preglednik certifikata</translation> <translation id="300526633675317032">Time će se izbrisati cijela pohrana web-lokacije veličine <ph name="SIZE_IN_KB" />.</translation> +<translation id="301521992641321250">Automatski blokirano</translation> <translation id="3115898365077584848">Prikaži informacije</translation> <translation id="3123473560110926937">Blokirano na nekim web-lokacijama</translation> <translation id="3190152372525844641">Uključite dopuštenja za Chrome u <ph name="BEGIN_LINK" />Postavkama Androida<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Sinkronizacija u pozadini</translation> <translation id="3822502789641063741">Izbrisati pohranu?</translation> <translation id="385051799172605136">Natrag</translation> +<translation id="3859306556332390985">Traži unaprijed</translation> <translation id="3955193568934677022">Web-lokacije mogu reproducirati zaštićeni sadržaj (preporučeno)</translation> <translation id="3987993985790029246">Kopiraj vezu</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> <translation id="4002066346123236978">Naslov</translation> <translation id="4008040567710660924">Dopusti kolačiće za određenu web-lokaciju.</translation> +<translation id="4046123991198612571">Sljedeća pjesma</translation> <translation id="4165986682804962316">Postavke web-lokacije</translation> <translation id="4226663524361240545">Obavijesti mogu uključiti vibriranje uređaja</translation> <translation id="4242533952199664413">Otvori postavke</translation> <translation id="4259722352634471385">Otvaranje je blokirano: <ph name="URL" /></translation> <translation id="4278390842282768270">Dopušteno</translation> +<translation id="429312253194641664">Web-lokacija reproducira medije</translation> <translation id="4433925000917964731">Jednostavna stranica koju pruža Google</translation> <translation id="4434045419905280838">Skočni prozori i preusmjeravanja</translation> <translation id="445467742685312942">Web-lokacijama je dopuštena reprodukcija zaštićenog sadržaja</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Opoziv svih dopuštenja za uređaj</translation> <translation id="4964199952259983386">Da bi Chrome mogao koristiti proširenu stvarnost, uključite i kameru u <ph name="BEGIN_LINK" />Androidovim postavkama<ph name="END_LINK" />.</translation> <translation id="497421865427891073">Idi naprijed</translation> +<translation id="4996978546172906250">Dijeli putem</translation> <translation id="5039804452771397117">Dopusti</translation> <translation id="5048398596102334565">Dopuštanje pristupa senzorima kretanja za web-lokacije (preporučeno)</translation> <translation id="5063480226653192405">Upotreba</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Izbriši</translation> <translation id="6697925417670533197">Aktivna preuzimanja</translation> <translation id="6746124502594467657">Pomakni dolje</translation> +<translation id="6766622839693428701">Prijeđite prstom prema dolje da biste zatvorili.</translation> <translation id="6782111308708962316">Onemogući web-lokacijama treće strane da spremaju i čitaju podatke kolačića.</translation> +<translation id="6790428901817661496">Reproduciraj</translation> <translation id="6818926723028410516">Odaberite stavke</translation> <translation id="6864395892908308021">Ovaj uređaj ne može čitati NFC</translation> <translation id="6910211073230771657">Izbrisano</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Web-lokacija upotrebljava vašu kameru</translation> <translation id="7817023149356982970">Odjavit ćete se s ove web-lokacije.</translation> <translation id="7828557259026017104">Kolačići su datoteke web-lokacija koje ste posjetili. Web-lokacije ih koriste kako bi zapamtile vaše postavke. Kolačiće trećih strana izrađuju ostale web-lokacije. Te web-lokacije posjeduju dio sadržaja prikazanog na web-stranici koju ste posjetili, primjerice oglase ili slike.</translation> +<translation id="7835852323729233924">Reprodukcija medija</translation> <translation id="7846076177841592234">Poništi odabir</translation> <translation id="7846621471902887024">Odjavit ćete se sa svih web-lokacija.</translation> <translation id="7882806643839505685">Dopuštanje zvuka za određenu web-lokaciju.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Jeste li sigurni da želite izbrisati sve lokalne podatke, uključujući kolačiće, i poništiti sva dopuštenja za ovu web-lokaciju?</translation> <translation id="8007176423574883786">Isključeno za ovaj uređaj</translation> <translation id="802154636333426148">Preuzimanje nije uspjelo</translation> +<translation id="8068648041423924542">Ne može se odabrati certifikat.</translation> <translation id="8087000398470557479">Sadržaj potječe s domene <ph name="DOMAIN_NAME" />, a omogućuje ga Google.</translation> <translation id="8116925261070264013">Bez zvuka</translation> <translation id="8131740175452115882">Potvrdi</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Web-lokacija upotrebljava vašu kameru i mikrofon</translation> <translation id="8380167699614421159">Ova web-lokacija prikazuje ometajuće ili obmanjujuće oglase</translation> <translation id="8394832520002899662">Dodirnite da biste se vratili na web-lokaciju</translation> +<translation id="8425213833346101688">Promijeni</translation> +<translation id="8441146129660941386">Traži unatrag</translation> <translation id="8447861592752582886">Opozovi odobrenje uređaja</translation> <translation id="8463851957836045671">Web-lokacija je brza</translation> <translation id="851751545965956758">Blokiraj povezivanje web-lokacija s uređajima</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Blokiraj kolačiće za određenu web-lokaciju.</translation> <translation id="8959122750345127698">Otvaranje je nedostupno: <ph name="URL" /></translation> <translation id="9019902583201351841">Upravljaju tvoji roditelji</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Pristup mikrofonu</translation> <translation id="965817943346481315">Blokiraj ako web-lokacija prikazuje ometajuće ili obmanjujuće oglase (preporučeno)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_hu.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_hu.xtb index 14a8e18489e..6e25bec47d2 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_hu.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_hu.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Tovább</translation> <translation id="1242008676835033345">Beágyazva itt: <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Leállítás</translation> +<translation id="1289742167380433257">Az adatforgalom csökkentése érdekében a Google optimalizálta az oldalon lévő képeket.</translation> <translation id="129382876167171263">A webhelyek által elmentett fájlok itt jelennek meg</translation> <translation id="1364532808393826295"><ph name="APP_NAME" />–<ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">A(z) <ph name="SITE_NAME" /> webhely hozzáadva</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Kérdezzen rá, mielőtt engedélyezi a webhelyek számára 3D-s térkép létrehozását az Ön környezetéről, valamint a kamera pozíciójának követését (ajánlott)</translation> <translation id="2212565012507486665">Cookie-k engedélyezése</translation> <translation id="2289270750774289114">Kérdezzen rá, ha valamelyik webhely szeretné felfedezni a közeli Bluetooth-eszközöket (ajánlott)</translation> +<translation id="2315043854645842844">Az ügyféloldali tanúsítványválasztást az operációs rendszer nem támogatja.</translation> <translation id="2359808026110333948">Tovább</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">Letöltés befejezve <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Másolt</translation> <translation id="2822354292072154809">Biztosan visszaállítja a(z) <ph name="CHOSEN_OBJECT_NAME" /> minden webhelyengedélyét?</translation> <translation id="2870560284913253234">Webhely</translation> +<translation id="2874939134665556319">Előző szám</translation> <translation id="2910701580606108292">Kérdezzen rá, mielőtt engedélyezné a webhelyek számára védett tartalmak lejátszását</translation> <translation id="2913331724188855103">Cookie-adatok mentésének és olvasásának engedélyezése a webhelyeken (ajánlott)</translation> <translation id="2968755619301702150">Tanúsítványmegtekintő</translation> <translation id="300526633675317032">Ezzel törli a webhely teljes tárhelyét: <ph name="SIZE_IN_KB" />.</translation> +<translation id="301521992641321250">Automatikusan letiltva</translation> <translation id="3115898365077584848">Információk megjelenítése</translation> <translation id="3123473560110926937">Letiltva egyes webhelyeken</translation> <translation id="3190152372525844641">A Chrome-ra vonatkozó engedélyek aktiválása az <ph name="BEGIN_LINK" />Android beállításaiban<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Szinkronizálás a háttérben</translation> <translation id="3822502789641063741">Törli a webhely tárhelyét?</translation> <translation id="385051799172605136">Vissza</translation> +<translation id="3859306556332390985">Ugrás előre</translation> <translation id="3955193568934677022">Engedélyezi a webhelyek számára a védett tartalmak lejátszását (ajánlott)</translation> <translation id="3987993985790029246">Link másolása</translation> <translation id="3991845972263764475">? / <ph name="BYTES_DOWNLOADED_WITH_UNITS" /></translation> <translation id="4002066346123236978">Cím</translation> <translation id="4008040567710660924">Adott webhely cookie-jainak engedélyezése.</translation> +<translation id="4046123991198612571">Következő szám</translation> <translation id="4165986682804962316">Webhelybeállítások</translation> <translation id="4226663524361240545">Az értesítések miatt rezeghet az eszköz</translation> <translation id="4242533952199664413">Beállítások megnyitása</translation> <translation id="4259722352634471385">Le van tiltva az ide vezető navigáció: <ph name="URL" /></translation> <translation id="4278390842282768270">Engedélyezve</translation> +<translation id="429312253194641664">Az egyik webhely médiatartalmat játszik le</translation> <translation id="4433925000917964731">Egyszerű oldal a Google-tól</translation> <translation id="4434045419905280838">Előugró ablakok és átirányítások</translation> <translation id="445467742685312942">Védett tartalmak lejátszásának engedélyezése a webhelyek számára</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Az eszköz összes engedélyének visszavonása</translation> <translation id="4964199952259983386">Ahhoz, hogy a Chrome használhassa az AR-t, kapcsolja be a kamerát is az <ph name="BEGIN_LINK" />Android-beállítások<ph name="END_LINK" /> között.</translation> <translation id="497421865427891073">Előrelépés</translation> +<translation id="4996978546172906250">Megosztás itt:</translation> <translation id="5039804452771397117">Engedélyezés</translation> <translation id="5048398596102334565">A mozgásérzékelőkhöz való hozzáférés engedélyezése a webhelyek számára (ajánlott)</translation> <translation id="5063480226653192405">Használat</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Törlés</translation> <translation id="6697925417670533197">Aktív letöltések</translation> <translation id="6746124502594467657">Mozgatás lefelé</translation> +<translation id="6766622839693428701">A bezáráshoz csúsztasson lefelé.</translation> <translation id="6782111308708962316">Megakadályozza, hogy harmadik felek webhelyei mentsék és olvassák a cookie-adatokat.</translation> +<translation id="6790428901817661496">Lejátszás</translation> <translation id="6818926723028410516">Válasszon elemeket</translation> <translation id="6864395892908308021">Ez az eszköz nem képes az NFC-alapú kommunikáció olvasására</translation> <translation id="6910211073230771657">Törölve</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Egy webhely használja az Ön kameráját</translation> <translation id="7817023149356982970">A rendszer kijelentkezteti majd erről a webhelyről</translation> <translation id="7828557259026017104">A cookie-k a felkeresett webhelyek által létrehozott fájlok. A webhelyek arra használják őket, hogy megjegyezzék az Ön preferenciáit. A harmadik féltől származó cookie-kat más webhelyek hozzák létre. Ezek a webhelyek birtokolják a meglátogatott weboldalon látható tartalom bizonyos részét (például hirdetéseket vagy képeket).</translation> +<translation id="7835852323729233924">Médiatartalom lejátszása…</translation> <translation id="7846076177841592234">Kijelölés törlése</translation> <translation id="7846621471902887024">Ki fog jelentkezni az összes webhelyről.</translation> <translation id="7882806643839505685">Egy adott webhely hangjának engedélyezése.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Biztosan törli a webhellyel kapcsolatos összes helyi adatot (a cookie-kkal együtt), és visszaállítja az összes engedélyt?</translation> <translation id="8007176423574883786">Kikapcsolva ezen az eszközön</translation> <translation id="802154636333426148">Nem sikerült a letöltés</translation> +<translation id="8068648041423924542">A tanúsítvány kiválasztása nem sikerült.</translation> <translation id="8087000398470557479">Ez a Google által megjelenített tartalom a(z) <ph name="DOMAIN_NAME" /> domainről származik.</translation> <translation id="8116925261070264013">Némítva</translation> <translation id="8131740175452115882">Megerősítés</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Egy webhely használja az Ön kameráját és mikrofonját</translation> <translation id="8380167699614421159">Ez a webhely tolakodó vagy félrevezető hirdetéseket jelenít meg</translation> <translation id="8394832520002899662">Koppintson a webhelyre való visszatéréshez</translation> +<translation id="8425213833346101688">Módosítás</translation> +<translation id="8441146129660941386">Ugrás visszafelé</translation> <translation id="8447861592752582886">Eszközengedély visszavonása</translation> <translation id="8463851957836045671">A webhely gyors</translation> <translation id="851751545965956758">Az eszközökhöz való csatlakozás megtiltása a webhelyeknek</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Adott webhely cookie-jainak letiltása.</translation> <translation id="8959122750345127698">Nem érhető el az ide vezető navigáció: <ph name="URL" /></translation> <translation id="9019902583201351841">Szülők által kezelt</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Hozzáférés a mikrofonhoz</translation> <translation id="965817943346481315">Letiltás, ha a webhely tolakodó vagy félrevezető hirdetéseket jelenít meg (ajánlott)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_hy.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_hy.xtb index ace5b49e9aa..065573fbedc 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_hy.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_hy.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Հաջորդը</translation> <translation id="1242008676835033345">Զետեղված է <ph name="WEBSITE_URL" /> կայքում</translation> <translation id="1272079795634619415">Դադարեցնել</translation> +<translation id="1289742167380433257">Թրաֆիկը խնայելու համար այս էջի պատկերները Google-ի կողմից օպտիմալացվել են։</translation> <translation id="129382876167171263">Կայքերի կողմից պահված ֆայլերը կցուցադրվեն այստեղ</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> – <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676"><ph name="SITE_NAME" /> կայքն ավելացվել է</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Կայքերի համար թույլտվություն խնդրել՝ ստեղծելու շրջակայքի եռաչափ քարտեզն ու հետագծելու ձեր տեսախցիկի դիրքը (խորհուրդ է տրվում)</translation> <translation id="2212565012507486665">Թույլատրել քուքիները</translation> <translation id="2289270750774289114">Հարցնել, երբ որևէ կայք ուզում է հայտնաբերել մոտակա Bluetooth սարքերը (խորհուրդ է տրվում)</translation> +<translation id="2315043854645842844">Տվյալ օպերացիոն համակարգը չի աջակցում սպասառուի կողմից վկայագրի ընտրությունը:</translation> <translation id="2359808026110333948">Շարունակել</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> ՄԲ</translation> <translation id="2434158240863470628">Ներբեռնումն ավարտված է՝ <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Պատճենվեց</translation> <translation id="2822354292072154809">Վերակայե՞լ բոլոր կայքերի թույլտվությունները <ph name="CHOSEN_OBJECT_NAME" />-ի համար:</translation> <translation id="2870560284913253234">Կայք</translation> +<translation id="2874939134665556319">Նախորդը</translation> <translation id="2910701580606108292">Պաշտպանված բովանդակություն նվագարկելու թույլտվություն հարցել</translation> <translation id="2913331724188855103">Թույլատրել կայքերին պահել և կարդալ քուքիների տվյալները (խորհուրդ է տրվում)</translation> <translation id="2968755619301702150">Վկայագրերի դիտում</translation> <translation id="300526633675317032">Կազատվի կայքի օգտագործած <ph name="SIZE_IN_KB" /> տարածք:</translation> +<translation id="301521992641321250">Ավտոմատ արգելափակված է</translation> <translation id="3115898365077584848">Ցուցադրել տեղեկությունները</translation> <translation id="3123473560110926937">Արգելափակված է որոշ կայքերում</translation> <translation id="3190152372525844641">Միացնել Chrome-ի թույլտվությունները <ph name="BEGIN_LINK" />Android-ի կարգավորումներում<ph name="END_LINK" />:</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Ֆոնային համաժամացում</translation> <translation id="3822502789641063741">Ջնջե՞լ կայքերի տվյալները:</translation> <translation id="385051799172605136">Հետ</translation> +<translation id="3859306556332390985">Որոնել դեպի առաջ</translation> <translation id="3955193568934677022">Թույլ տալ կայքերին նվագարկել պաշտպանված բովանդակությունը (խորհուրդ է տրվում)</translation> <translation id="3987993985790029246">Պատճենել հղումը</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> <translation id="4002066346123236978">Վերնագիր</translation> <translation id="4008040567710660924">Թույլատրել քուքիները կոնկրետ կայքի համար:</translation> +<translation id="4046123991198612571">Հաջորդը</translation> <translation id="4165986682804962316">Կայքի կարգավորումներ</translation> <translation id="4226663524361240545">Ծանուցումների ժամանակ սարքը կթրթռա</translation> <translation id="4242533952199664413">Բացել կարգավորումները</translation> <translation id="4259722352634471385">Նավարկումն արգելափակված է՝ <ph name="URL" /></translation> <translation id="4278390842282768270">Թույլատրված է</translation> +<translation id="429312253194641664">Կայքում մեդիա ֆայլ է նվագարկվում</translation> <translation id="4433925000917964731">Էջի Lite տարբերակը տրամադրվել է Google-ի կողմից</translation> <translation id="4434045419905280838">Ելնող պատուհաններ և վերահղում</translation> <translation id="445467742685312942">Թույլատրել կայքերին նվագարկել պաշտպանված բովանդակություն</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Չեղարկել սարքի բոլոր թույլտվությունները</translation> <translation id="4964199952259983386">Chrome-ին AR ռեժիմն օգտագործելու թույլտվություն տալու համար միացրեք նաև տեսախցիկը <ph name="BEGIN_LINK" />Android-ի կարգավորումներում<ph name="END_LINK" />։</translation> <translation id="497421865427891073">Առաջ գնալ</translation> +<translation id="4996978546172906250">Համօգտագործման միջոցը`</translation> <translation id="5039804452771397117">Թույլ տալ</translation> <translation id="5048398596102334565">Թույլ տալ կայքերին օգտագործել ձեր տվիչները (խորհուրդ է տրվում)</translation> <translation id="5063480226653192405">Վիճակագրություն</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Մաքրել</translation> <translation id="6697925417670533197">Ընթացիկ ներբեռնումներ</translation> <translation id="6746124502594467657">Տեղափոխել վար</translation> +<translation id="6766622839693428701">Փակելու համար մատը սահեցրեք ներքև։</translation> <translation id="6782111308708962316">Թույլ չտալ երրորդ կողմի կայքերին պահել և կարդալ քուքիների տվյալները</translation> +<translation id="6790428901817661496">Նվագարկել</translation> <translation id="6818926723028410516">Ընտրեք տարրեր</translation> <translation id="6864395892908308021">Այս սարքում NFC-ն չի աջակցվում</translation> <translation id="6910211073230771657">Ջնջված</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Կայքն օգտագործում է ձեր տեսախցիկը</translation> <translation id="7817023149356982970">Դուք դուրս կգաք այս կայքից։</translation> <translation id="7828557259026017104">Քուքիները ֆայլեր են, որոնք ստեղծվում են ձեր այցելած կայքերի կողմից։ Կայքերն օգտագործում են դրանք՝ ձեր նախընտրությունները հիշելու համար։ Երրորդ կողմի քուքիները ստեղծվում են այլ կայքերի կողմից։ Այս կայքերն ունեն որոշակի բովանդակություն, օր․՝ գովազդ կամ պատկերներ, որոնք դուք տեսնում եք ձեր այցելած կայքում։</translation> +<translation id="7835852323729233924">Մեդիա բովանդակության նվագարկում</translation> <translation id="7846076177841592234">Չեղարկել ընտրվածքը</translation> <translation id="7846621471902887024">Դուք դուրս կգաք բոլոր կայքերից։</translation> <translation id="7882806643839505685">Թույլատրել ձայնը առանձին կայքերում</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Համոզվա՞ծ եք, որ ուզում եք մաքրել բոլոր տեղային տվյալները, այդ թվում նաև քուքիները, և զրոյացնել այս կայքի թույլտվությունները:</translation> <translation id="8007176423574883786">Անջատված է այս սարքի համար</translation> <translation id="802154636333426148">Ներբեռնումը ձախողվեց</translation> +<translation id="8068648041423924542">Չի հաջողվում ընտրել վկայագիրը:</translation> <translation id="8087000398470557479">Այս բովանդակությունը <ph name="DOMAIN_NAME" />-ից է, մատուցվում է Google-ի կողմից:</translation> <translation id="8116925261070264013">Անջատած ձայնով կայքեր</translation> <translation id="8131740175452115882">Հաստատել</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Կայքն օգտագործում է ձեր տեսախցիկն ու խոսափողը</translation> <translation id="8380167699614421159">Այս կայքը հոգնեցնող կամ մոլորեցնող գովազդ է ցուցադրում։</translation> <translation id="8394832520002899662">Հպեք՝ կայք վերադառնալու համար</translation> +<translation id="8425213833346101688">Փոխել</translation> +<translation id="8441146129660941386">Որոնել դեպի հետ</translation> <translation id="8447861592752582886">Արգելել սարքի օգտագործումը</translation> <translation id="8463851957836045671">Կայքը բեռնվում է արագ</translation> <translation id="851751545965956758">Արգելել կայքերին միանալ սարքերին</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Արգելափակել քուքիները կոնկրետ կայքի համար:</translation> <translation id="8959122750345127698">Նավարկումն անհասանելի է՝ <ph name="URL" /></translation> <translation id="9019902583201351841">Կառավարվում է ձեր ծնողների կողմից</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Խոսափողի օգտագործում</translation> <translation id="965817943346481315">Արգելափակել, եթե կայքը հոգնեցնող կամ մոլորեցնող գովազդ է ցուցադրում (խորհուրդ է տրվում)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_id.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_id.xtb index 58175d33ffe..e41a743fec6 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_id.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_id.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Berikutnya</translation> <translation id="1242008676835033345">Disematkan di <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Berhenti</translation> +<translation id="1289742167380433257">Untuk menghemat data Anda, gambar di halaman ini telah dioptimalkan oleh Google.</translation> <translation id="129382876167171263">File yang disimpan situs muncul di sini</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> - <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Situs <ph name="SITE_NAME" /> ditambahkan</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Tanyakan sebelum mengizinkan situs membuat peta 3D untuk area di sekeliling Anda atau melacak posisi kamera (direkomendasikan)</translation> <translation id="2212565012507486665">Izinkan cookie</translation> <translation id="2289270750774289114">Tanyakan saat situs ingin menemukan perangkat Bluetooth di sekitar (direkomendasikan)</translation> +<translation id="2315043854645842844">Pilihan sertifikat sisi klien tidak didukung oleh sistem operasi.</translation> <translation id="2359808026110333948">Lanjutkan</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">Download selesai <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Disalin</translation> <translation id="2822354292072154809">Yakin ingin menyetel ulang semua izin situs untuk <ph name="CHOSEN_OBJECT_NAME" />?</translation> <translation id="2870560284913253234">Situs</translation> +<translation id="2874939134665556319">Lagu sebelumnya</translation> <translation id="2910701580606108292">Tanyakan sebelum mengizinkan situs untuk memutar konten yang dilindungi</translation> <translation id="2913331724188855103">Izinkan situs untuk menyimpan dan membaca data cookie (disarankan)</translation> <translation id="2968755619301702150">Penampil sertifikat</translation> <translation id="300526633675317032">Ini akan menghapus seluruh penyimpanan situs web, sebesar <ph name="SIZE_IN_KB" />.</translation> +<translation id="301521992641321250">Diblokir secara otomatis</translation> <translation id="3115898365077584848">Tampilkan Info</translation> <translation id="3123473560110926937">Diblokir di beberapa situs</translation> <translation id="3190152372525844641">Aktifkan izin untuk Chrome di <ph name="BEGIN_LINK" />Setelan Android<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Sinkronisasi latar belakang</translation> <translation id="3822502789641063741">Kosongkan penyimpanan situs?</translation> <translation id="385051799172605136">Kembali</translation> +<translation id="3859306556332390985">Cari maju</translation> <translation id="3955193568934677022">Izinkan situs memutar konten yang dilindungi (direkomendasikan)</translation> <translation id="3987993985790029246">Salin link</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">Judul</translation> <translation id="4008040567710660924">Izinkan cookie untuk situs tertentu.</translation> +<translation id="4046123991198612571">Lagu berikutnya</translation> <translation id="4165986682804962316">Setelan situs</translation> <translation id="4226663524361240545">Notifikasi dapat membuat perangkat bergetar</translation> <translation id="4242533952199664413">Buka setelan</translation> <translation id="4259722352634471385">Navigasi diblokir: <ph name="URL" /></translation> <translation id="4278390842282768270">Diizinkan</translation> +<translation id="429312253194641664">Sebuah situs sedang memutar media</translation> <translation id="4433925000917964731">Halaman ringan yang ditampilkan oleh Google.</translation> <translation id="4434045419905280838">Pop-up dan pengalihan</translation> <translation id="445467742685312942">Izinkan situs memutar konten yang dilindungi</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Cabut semua izin untuk perangkat</translation> <translation id="4964199952259983386">Untuk mengizinkan Chrome menggunakan Augmented Reality (AR), aktifkan juga kamera di <ph name="BEGIN_LINK" />Setelan Android<ph name="END_LINK" />.</translation> <translation id="497421865427891073">Maju</translation> +<translation id="4996978546172906250">Bagikan dengan</translation> <translation id="5039804452771397117">Izinkan</translation> <translation id="5048398596102334565">Mengizinkan situs mengakses sensor gerakan (disarankan)</translation> <translation id="5063480226653192405">Penggunaan</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Hapus</translation> <translation id="6697925417670533197">Download aktif</translation> <translation id="6746124502594467657">Berpindah ke bawah</translation> +<translation id="6766622839693428701">Geser ke bawah untuk menutup.</translation> <translation id="6782111308708962316">Cegah situs web pihak ketiga agar tidak menyimpan dan membaca data cookie</translation> +<translation id="6790428901817661496">Putar</translation> <translation id="6818926723028410516">Pilih item</translation> <translation id="6864395892908308021">Perangkat ini tidak dapat membaca NFC</translation> <translation id="6910211073230771657">Dihapus</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Situs menggunakan kamera Anda</translation> <translation id="7817023149356982970">Anda akan logout dari situs ini.</translation> <translation id="7828557259026017104">Cookie adalah file yang dibuat oleh situs yang Anda kunjungi. Situs menggunakannya untuk mengingat preferensi Anda. Cookie pihak ketiga dibuat oleh situs lain. Situs seperti ini adalah pemilik beberapa konten, misalnya iklan atau gambar, yang terlihat di halaman yang Anda kunjungi.</translation> +<translation id="7835852323729233924">Media yang sedang diputar</translation> <translation id="7846076177841592234">Batalkan pilihan</translation> <translation id="7846621471902887024">Anda akan logout dari semua situs.</translation> <translation id="7882806643839505685">Izinkan suara untuk situs tertentu.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Yakin ingin menghapus semua data lokal, termasuk cookie, dan menyetel ulang semua izin untuk situs web ini?</translation> <translation id="8007176423574883786">Dinonaktifkan untuk perangkat ini</translation> <translation id="802154636333426148">Download gagal</translation> +<translation id="8068648041423924542">Tidak dapat memilih sertifikat.</translation> <translation id="8087000398470557479">Konten ini dari <ph name="DOMAIN_NAME" />, dikirimkan oleh Google.</translation> <translation id="8116925261070264013">Dinonaktifkan</translation> <translation id="8131740175452115882">Konfirmasi</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Situs menggunakan kamera dan mikrofon Anda</translation> <translation id="8380167699614421159">Situs ini menampilkan iklan yang mengganggu atau menyesatkan</translation> <translation id="8394832520002899662">Ketuk untuk kembali ke situs</translation> +<translation id="8425213833346101688">Ubah</translation> +<translation id="8441146129660941386">Cari mundur</translation> <translation id="8447861592752582886">Cabut izin perangkat</translation> <translation id="8463851957836045671">Situs ini cepat</translation> <translation id="851751545965956758">Blokir situs agar tidak terhubung ke perangkat</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Blokir cookie untuk situs tertentu.</translation> <translation id="8959122750345127698">Navigasi tidak dapat dijangkau: <ph name="URL" /></translation> <translation id="9019902583201351841">Dikelola oleh orang tua Anda</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Akses mikrofon Anda</translation> <translation id="965817943346481315">Blokir jika situs menampilkan iklan yang mengganggu atau menyesatkan (direkomendasikan)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_is.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_is.xtb index e041209ca54..b5a142669c2 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_is.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_is.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Áfram</translation> <translation id="1242008676835033345">Fellt inn á <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Stöðva</translation> +<translation id="1289742167380433257">Þessar myndir voru fínstilltar af Google til að spara gögn.</translation> <translation id="129382876167171263">Skrár sem vefsvæði vista birtast hér</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> – <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Vefsvæðinu <ph name="SITE_NAME" /> bætt við</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Spyrja áður en vefsvæðum er leyft að búa til þrívíddarkort af umhverfinu eða rekja staðsetningu myndavélarinnar (ráðlagt)</translation> <translation id="2212565012507486665">Leyfa fótspor</translation> <translation id="2289270750774289114">Spyrja þegar vefsvæði vill finna nálæg Bluetooth-tæki (ráðlagt)</translation> +<translation id="2315043854645842844">Stýrikerfið styður ekki vottorðsval hjá biðlara.</translation> <translation id="2359808026110333948">Halda áfram</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">Niðurhali lokið <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Afritað</translation> <translation id="2822354292072154809">Viltu örugglega endurstilla allar heimildir vefsvæða fyrir „<ph name="CHOSEN_OBJECT_NAME" />“?</translation> <translation id="2870560284913253234">Vefsvæði</translation> +<translation id="2874939134665556319">Fyrra lag</translation> <translation id="2910701580606108292">Spyrja áður en vefsvæðum er veitt heimild til að spila varið efni</translation> <translation id="2913331724188855103">Leyfa vefsvæðum að vista og lesa fótsporagögn (ráðlagt)</translation> <translation id="2968755619301702150">Vottorðaskoðari</translation> <translation id="300526633675317032">Þetta mun losa alls um <ph name="SIZE_IN_KB" /> af geymslu vefsvæða.</translation> +<translation id="301521992641321250">Sjálfkrafa lokað á</translation> <translation id="3115898365077584848">Sýna upplýsingar</translation> <translation id="3123473560110926937">Útilokaðar á sumum vefsvæðum</translation> <translation id="3190152372525844641">Kveiktu á heimildum fyrir Chrome í <ph name="BEGIN_LINK" />stillingum Android<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Samstilling í bakgrunni</translation> <translation id="3822502789641063741">Hreinsa geymslu vefsvæða?</translation> <translation id="385051799172605136">Til baka</translation> +<translation id="3859306556332390985">Leita áfram</translation> <translation id="3955193568934677022">Leyfa vefsvæðum að spila varið efni (ráðlagt)</translation> <translation id="3987993985790029246">Afrita tengil</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> <translation id="4002066346123236978">Heiti</translation> <translation id="4008040567710660924">Leyfa fótspor fyrir tiltekið vefsvæði.</translation> +<translation id="4046123991198612571">Næsta lag</translation> <translation id="4165986682804962316">Svæðisstillingar</translation> <translation id="4226663524361240545">Tilkynningar gætu látið tækið titra</translation> <translation id="4242533952199664413">Opna stillingar</translation> <translation id="4259722352634471385">Lokað er fyrir skoðun: <ph name="URL" /></translation> <translation id="4278390842282768270">Leyft</translation> +<translation id="429312253194641664">Vefsvæði er að spila efni</translation> <translation id="4433925000917964731">Léttútgáfa síðu frá Google</translation> <translation id="4434045419905280838">Sprettigluggar og framsendingar</translation> <translation id="445467742685312942">Leyfa vefsvæðum að spila varið efni</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Afturkalla allar heimildir fyrir þetta tæki</translation> <translation id="4964199952259983386">Til að leyfa Chrome að nota AR þarftu einnig að kveikja á myndavél í <ph name="BEGIN_LINK" />stillingum Android<ph name="END_LINK" />.</translation> <translation id="497421865427891073">Áfram</translation> +<translation id="4996978546172906250">Deila með</translation> <translation id="5039804452771397117">Leyfa</translation> <translation id="5048398596102334565">Leyfa vefsvæðum að fá aðgang að hreyfiskynjurunum (ráðlagt)</translation> <translation id="5063480226653192405">Notkun</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Hreinsa</translation> <translation id="6697925417670533197">Niðurhal í gangi</translation> <translation id="6746124502594467657">Færa niður</translation> +<translation id="6766622839693428701">Strjúktu niður til að loka.</translation> <translation id="6782111308708962316">Koma í veg fyrir að vefsvæði þriðju aðila geti vistað og lesið fótsporagögn</translation> +<translation id="6790428901817661496">Spila</translation> <translation id="6818926723028410516">Veldu atriði</translation> <translation id="6864395892908308021">Þetta tæki getur ekki lesið NFC</translation> <translation id="6910211073230771657">Eytt</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Vefsvæði er að nota myndavélina</translation> <translation id="7817023149356982970">Þú verður skráð(ur) út af þessu vefsvæði.</translation> <translation id="7828557259026017104">Fótspor eru skrár sem myndast á vefsvæðum sem þú heimsækir. Vefsvæði geta notað þau til að muna kjörstillingarnar þínar. Fótspor frá þriðja aðila eru búin til af öðrum vefsvæðum. Þessi vefsvæði eiga eitthvað af efninu, eins og auglýsingar eða myndir, sem þú sérð á vefsíðunni sem þú heimsækir.</translation> +<translation id="7835852323729233924">Spilar efni</translation> <translation id="7846076177841592234">Hætta við val</translation> <translation id="7846621471902887024">Þú verður skráð(ur) út af öllum vefsvæðum.</translation> <translation id="7882806643839505685">Leyfa hljóð á tilteknu vefsvæði.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Ertu viss um að þú viljir hreinsa öll staðbundin gögn fyrir þetta vefsvæði, þar á meðal fótspor, og endurstilla allar heimildir þess?</translation> <translation id="8007176423574883786">Slökkt fyrir þetta tæki</translation> <translation id="802154636333426148">Niðurhal mistókst</translation> +<translation id="8068648041423924542">Ekki er hægt að velja vottorðið.</translation> <translation id="8087000398470557479">Þetta efni er frá <ph name="DOMAIN_NAME" />, birt af Google.</translation> <translation id="8116925261070264013">Þögguð</translation> <translation id="8131740175452115882">Staðfesta</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Vefsvæði er að nota myndavélina þína og hljóðnemann</translation> <translation id="8380167699614421159">Þetta vefsvæði sýnir ágengar eða villandi auglýsingar</translation> <translation id="8394832520002899662">Ýttu til að fara aftur á vefsvæðið</translation> +<translation id="8425213833346101688">Breyta</translation> +<translation id="8441146129660941386">Spóla til baka</translation> <translation id="8447861592752582886">Afturkalla tækjaheimild</translation> <translation id="8463851957836045671">Vefsvæðið er hratt</translation> <translation id="851751545965956758">Ekki leyfa vefsvæðum að tengjast tækjum</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Lokaðu á fótspor fyrir tiltekið vefsvæði.</translation> <translation id="8959122750345127698">Ekki næst samband: <ph name="URL" /></translation> <translation id="9019902583201351841">Stjórnað af foreldrum þínum</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Aðgangur að hljóðnemanum</translation> <translation id="965817943346481315">Loka fyrir ef vefsvæði sýnir ágengar eða villandi auglýsingar (ráðlagt)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_it.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_it.xtb index 77ff590249a..977e68105e4 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_it.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_it.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Avanti</translation> <translation id="1242008676835033345">Incorporato su <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Interrompi</translation> +<translation id="1289742167380433257">Per ridurre il consumo di dati, le immagini di questa pagina sono state ottimizzate da Google.</translation> <translation id="129382876167171263">I file salvati dai siti web vengono mostrati qui</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> - <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Sito <ph name="SITE_NAME" /> aggiunto</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Chiedi conferma prima di consentire ai siti di creare una mappa 3D dell'ambiente circostante o di monitorare la posizione della fotocamera (opzione consigliata)</translation> <translation id="2212565012507486665">Consenti cookie</translation> <translation id="2289270750774289114">Chiedi conferma quando un sito vuole rilevare i dispositivi Bluetooth nelle vicinanze (opzione consigliata)</translation> +<translation id="2315043854645842844">La selezione del certificato lato client non è supportata dal sistema operativo.</translation> <translation id="2359808026110333948">Continua</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">Download completato: <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Copiata</translation> <translation id="2822354292072154809">Vuoi reimpostare tutte le autorizzazioni del sito per <ph name="CHOSEN_OBJECT_NAME" />?</translation> <translation id="2870560284913253234">Sito</translation> +<translation id="2874939134665556319">Traccia precedente</translation> <translation id="2910701580606108292">Chiedi prima di consentire ai siti di riprodurre contenuti protetti</translation> <translation id="2913331724188855103">Consenti ai siti di salvare e leggere i dati dei cookie (opzione consigliata)</translation> <translation id="2968755619301702150">Visualizzatore certificati</translation> <translation id="300526633675317032">Verranno cancellati tutti i <ph name="SIZE_IN_KB" /> di memoria utilizzata dai siti web.</translation> +<translation id="301521992641321250">Bloccata automaticamente</translation> <translation id="3115898365077584848">Mostra informazioni</translation> <translation id="3123473560110926937">Bloccati su alcuni siti</translation> <translation id="3190152372525844641">Abilita le autorizzazioni per Chrome in <ph name="BEGIN_LINK" />Impostazioni Android<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Sincronizzazione in background</translation> <translation id="3822502789641063741">Cancellare i dati dei siti?</translation> <translation id="385051799172605136">Indietro</translation> +<translation id="3859306556332390985">Posiziona avanti</translation> <translation id="3955193568934677022">Consenti ai siti di riprodurre i contenuti protetti (opzione consigliata)</translation> <translation id="3987993985790029246">Copia link</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> di ?</translation> <translation id="4002066346123236978">Titolo</translation> <translation id="4008040567710660924">Consenti i cookie per un sito specifico.</translation> +<translation id="4046123991198612571">Traccia successiva</translation> <translation id="4165986682804962316">Impostazioni sito</translation> <translation id="4226663524361240545">Le notifiche possono far vibrare il dispositivo</translation> <translation id="4242533952199664413">Apri le impostazioni</translation> <translation id="4259722352634471385">Navigazione bloccata: <ph name="URL" /></translation> <translation id="4278390842282768270">Consentito</translation> +<translation id="429312253194641664">Un sito sta riproducendo contenuti multimediali</translation> <translation id="4433925000917964731">Pagina Lite fornita da Google</translation> <translation id="4434045419905280838">Popup e reindirizzamenti</translation> <translation id="445467742685312942">Consenti ai siti di riprodurre contenuti protetti</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Revoca tutte le autorizzazioni per il dispositivo</translation> <translation id="4964199952259983386">Per consentire a Chrome di utilizzare l'AR, attiva anche la fotocamera nelle <ph name="BEGIN_LINK" />Impostazioni Android<ph name="END_LINK" />.</translation> <translation id="497421865427891073">Avanti</translation> +<translation id="4996978546172906250">Condividi tramite</translation> <translation id="5039804452771397117">Consenti</translation> <translation id="5048398596102334565">Consenti ai siti di accedere ai sensori di movimento (opzione consigliata)</translation> <translation id="5063480226653192405">Utilizzo</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Cancella</translation> <translation id="6697925417670533197">Download attivi</translation> <translation id="6746124502594467657">Sposta giù</translation> +<translation id="6766622839693428701">Fai scorrere verso il basso per chiudere.</translation> <translation id="6782111308708962316">Impedisci ai siti web di terze parti di salvare e leggere i dati dei cookie</translation> +<translation id="6790428901817661496">Play</translation> <translation id="6818926723028410516">Seleziona elementi</translation> <translation id="6864395892908308021">Questo dispositivo non può leggere la tecnologia NFC</translation> <translation id="6910211073230771657">Eliminato</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Un sito sta utilizzando la fotocamera</translation> <translation id="7817023149356982970">Uscirai da questo sito.</translation> <translation id="7828557259026017104">I cookie sono file creati dai siti web visitati, che li usano per memorizzare le tue preferenze. I cookie di terze parti vengono creati da altri siti, che sono proprietari di alcuni dei contenuti, ad esempio annunci o immagini, che vengono visualizzati nella pagina web visitata.</translation> +<translation id="7835852323729233924">Riproduzione media</translation> <translation id="7846076177841592234">Annulla selezione</translation> <translation id="7846621471902887024">Il tuo account verrà disconnesso da tutti i siti.</translation> <translation id="7882806643839505685">Consenti l'audio per un sito specifico.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Vuoi cancellare tutti i dati locali, inclusi i cookie, e reimpostare tutte le autorizzazioni relative al sito web?</translation> <translation id="8007176423574883786">Disattivata per questo dispositivo</translation> <translation id="802154636333426148">Download non riuscito</translation> +<translation id="8068648041423924542">Impossibile selezionare il certificato.</translation> <translation id="8087000398470557479">Questi contenuti derivano da <ph name="DOMAIN_NAME" /> e sono offerti da Google.</translation> <translation id="8116925261070264013">Con audio disattivato</translation> <translation id="8131740175452115882">Conferma</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Un sito sta utilizzando la fotocamera e il microfono</translation> <translation id="8380167699614421159">Questo sito mostra annunci invasivi o fuorvianti</translation> <translation id="8394832520002899662">Tocca per tornare al sito.</translation> +<translation id="8425213833346101688">Cambia</translation> +<translation id="8441146129660941386">Posiziona indietro</translation> <translation id="8447861592752582886">Revoca autorizzazione dispositivo</translation> <translation id="8463851957836045671">Il sito è veloce</translation> <translation id="851751545965956758">Impedisci ai siti di connettersi ai dispositivi</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Blocca i cookie per un sito specifico.</translation> <translation id="8959122750345127698">Navigazione inaccessibile: <ph name="URL" /></translation> <translation id="9019902583201351841">Gestito dai genitori</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Accesso al microfono</translation> <translation id="965817943346481315">Blocca se il sito mostra annunci invasivi o fuorvianti (consigliato)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_iw.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_iw.xtb index 082b225d2eb..73376a04109 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_iw.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_iw.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">הבא</translation> <translation id="1242008676835033345">מוטמע ב-<ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">הפסק</translation> +<translation id="1289742167380433257">כדי לחסוך לך נתונים, התמונות בדף הזה עברו אופטימיזציה על ידי Google.</translation> <translation id="129382876167171263">קבצים שנשמרו על ידי אתרים מופיעים כאן</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> – <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">האתר <ph name="SITE_NAME" /> נוסף</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">תוצג שאלה לפני מתן הרשאה לאתרים ליצור מפה בתלת ממד של הסביבה שלך או לעקוב אחר מיקום המצלמה (מומלץ)</translation> <translation id="2212565012507486665">אישור קובצי cookie</translation> <translation id="2289270750774289114">המערכת מבקשת אישור כשאתר רוצה לאתר התקני Bluetooth קרובים (מומלץ)</translation> +<translation id="2315043854645842844">מערכת ההפעלה אינה תומכת בבחירת אישור בצד הלקוח.</translation> <translation id="2359808026110333948">המשך</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">ההורדה הושלמה <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">הועתק</translation> <translation id="2822354292072154809">לאפס את כל הרשאות האתר בשביל <ph name="CHOSEN_OBJECT_NAME" />?</translation> <translation id="2870560284913253234">אתר</translation> +<translation id="2874939134665556319">הרצועה הקודמת</translation> <translation id="2910701580606108292">הצגת שאלה לפני מתן הרשאה לאתרים להפעיל תוכן מוגן</translation> <translation id="2913331724188855103">אתרים יוכלו לשמור ולקרוא נתונים של קובצי Cookie (מומלץ)</translation> <translation id="2968755619301702150">מציג האישורים</translation> <translation id="300526633675317032">פעולה זו תמחק את כל נתוני האתר המאוחסנים (<ph name="SIZE_IN_KB" />).</translation> +<translation id="301521992641321250">נחסמה אוטומטית</translation> <translation id="3115898365077584848">הצג פרטים</translation> <translation id="3123473560110926937">חסומות בחלק מהאתרים</translation> <translation id="3190152372525844641">הפעל הרשאות בשביל Chrome ב<ph name="BEGIN_LINK" />הגדרות Android<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">סינכרון ברקע</translation> <translation id="3822502789641063741">למחוק נתוני אתר מהאחסון?</translation> <translation id="385051799172605136">חזרה</translation> +<translation id="3859306556332390985">הרץ קדימה</translation> <translation id="3955193568934677022">אתרים יוכלו להפעיל תוכן מוגן (מומלץ)</translation> <translation id="3987993985790029246">העתק קישור</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">כותרת</translation> <translation id="4008040567710660924">אישור קובצי Cookie של אתר מסוים.</translation> +<translation id="4046123991198612571">הרצועה הבאה</translation> <translation id="4165986682804962316">הגדרות לאתרים</translation> <translation id="4226663524361240545">רטט של המכשיר אפשרי כשמתקבלת הודעה</translation> <translation id="4242533952199664413">פתח את 'הגדרות'</translation> <translation id="4259722352634471385">הניווט חסום: <ph name="URL" /></translation> <translation id="4278390842282768270">מותר</translation> +<translation id="429312253194641664">אתר מסוים מפעיל מדיה</translation> <translation id="4433925000917964731">גרסת Lite של הדף נוצרה על ידי Google</translation> <translation id="4434045419905280838">חלונות קופצים והפניות אוטומטיות</translation> <translation id="445467742685312942">מתן הרשאה לאתרים להציג תוכן מוגן</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">ביטול כל ההרשאות בשביל המכשיר</translation> <translation id="4964199952259983386">כדי לאפשר ל-Chrome להשתמש ב-AR, צריך גם להפעיל את המצלמה ב<ph name="BEGIN_LINK" />הגדרות Android<ph name="END_LINK" />.</translation> <translation id="497421865427891073">המשך קדימה</translation> +<translation id="4996978546172906250">שיתוף באמצעות</translation> <translation id="5039804452771397117">זה בסדר</translation> <translation id="5048398596102334565">התרת גישה של אתרים אל חיישני התנועה (מומלץ)</translation> <translation id="5063480226653192405">שימוש</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">ניקוי</translation> <translation id="6697925417670533197">הורדות פעילות</translation> <translation id="6746124502594467657">הזז למטה</translation> +<translation id="6766622839693428701">החלקה מטה סוגרת.</translation> <translation id="6782111308708962316">אתרים של צד שלישי לא יוכלו לשמור ולקרוא נתונים של קובצי cookie</translation> +<translation id="6790428901817661496">הפעל</translation> <translation id="6818926723028410516">בחירת פריטים</translation> <translation id="6864395892908308021">NFC לא נתמך במכשיר הזה</translation> <translation id="6910211073230771657">נמחק</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">אתר כלשהו משתמש במצלמה שלך</translation> <translation id="7817023149356982970">המערכת תוציא אותך מהאתר הזה.</translation> <translation id="7828557259026017104">קובצי cookie נוצרים על ידי האתרים שביקרת בהם. האתרים משתמשים בהם כדי לזכור את ההעדפות שלך. קובצי cookie של צד שלישי נוצרים על-ידי אתרים אחרים. האתרים האלה הם הבעלים של חלק מהתוכן בדף האינטרנט שביקרת בו, למשל מודעות או תמונות.</translation> +<translation id="7835852323729233924">מדיה פועלת</translation> <translation id="7846076177841592234">בטל את הבחירה</translation> <translation id="7846621471902887024">תתבצע יציאה מכל האתרים.</translation> <translation id="7882806643839505685">מתן הרשאה להשמעת צלילים באתר ספציפי.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">האם אתה בטוח שברצונך לנקות את כל הנתונים המקומיים, כולל קובצי Cookie, ולאפס את כל ההרשאות של האתר הזה?</translation> <translation id="8007176423574883786">כבוי בשביל המכשיר הזה</translation> <translation id="802154636333426148">ההורדה נכשלה</translation> +<translation id="8068648041423924542">אין אפשרות לבחור אישור.</translation> <translation id="8087000398470557479">התוכן הזה הוא מ-<ph name="DOMAIN_NAME" />, ומוגש על-ידי Google.</translation> <translation id="8116925261070264013">מושתקים</translation> <translation id="8131740175452115882">אישור</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">אתר כלשהו משתמש במצלמה ובמיקרופון שלך</translation> <translation id="8380167699614421159">באתר הזה מוצגות מודעות מפריעות או מטעות</translation> <translation id="8394832520002899662">כדי לחזור לאתר, יש להקיש כאן</translation> +<translation id="8425213833346101688">שנה</translation> +<translation id="8441146129660941386">הרץ לאחור</translation> <translation id="8447861592752582886">שלול הרשאות מכשיר</translation> <translation id="8463851957836045671">האתר הזה מהיר</translation> <translation id="851751545965956758">חסימת התחברות של אתרים אל התקנים</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">חסימת קובצי Cookie של אתר מסוים.</translation> <translation id="8959122750345127698">הניווט לא אפשרי: <ph name="URL" /></translation> <translation id="9019902583201351841">מנוהל על-ידי ההורים שלך</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">גישה למיקרופון שלך</translation> <translation id="965817943346481315">חסימה אם באתר מוצגות מודעות מפריעות או מטעות (מומלץ)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ja.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ja.xtb index 7283d03500b..64d03bde87f 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ja.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ja.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">次へ</translation> <translation id="1242008676835033345"><ph name="WEBSITE_URL" /> に埋め込まれたページ</translation> <translation id="1272079795634619415">中止</translation> +<translation id="1289742167380433257">データを節約するため、このページの画像は Google によって最適化されています。</translation> <translation id="129382876167171263">ウェブサイトによって保存されたファイルがここに表示されます</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> - <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">サイト <ph name="SITE_NAME" /> を追加しました</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">サイトに周囲の 3D マップの作成またはカメラ位置の追跡を許可する前に確認します(推奨)</translation> <translation id="2212565012507486665">Cookie を許可</translation> <translation id="2289270750774289114">サイトから近くにある Bluetooth デバイスの検出を求められたときに確認する(推奨)</translation> +<translation id="2315043854645842844">オペレーティング システムでサポートされていないため、クライアント側で証明書を選択することはできません。</translation> <translation id="2359808026110333948">続行</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">ダウンロードが完了しました<ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">コピーしました</translation> <translation id="2822354292072154809">「<ph name="CHOSEN_OBJECT_NAME" />」に関するすべてのサイト権限をリセットしてもよろしいですか?</translation> <translation id="2870560284913253234">サイト</translation> +<translation id="2874939134665556319">前のトラック</translation> <translation id="2910701580606108292">保護されたコンテンツの再生をサイトに許可する前に確認する</translation> <translation id="2913331724188855103">サイトに Cookie データの保存と読み取りを許可する(推奨)</translation> <translation id="2968755619301702150">証明書ビューア</translation> <translation id="300526633675317032">ウェブサイトのストレージ <ph name="SIZE_IN_KB" /> のデータをすべて削除します。</translation> +<translation id="301521992641321250">自動ブロックされました</translation> <translation id="3115898365077584848">情報を表示</translation> <translation id="3123473560110926937">一部のサイトでブロックされています</translation> <translation id="3190152372525844641"><ph name="BEGIN_LINK" />Android の設定<ph name="END_LINK" />で Chrome の権限を有効にしてください。</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">バックグラウンド同期</translation> <translation id="3822502789641063741">サイトのストレージ データを削除しますか?</translation> <translation id="385051799172605136">戻る</translation> +<translation id="3859306556332390985">前方にシーク再生</translation> <translation id="3955193568934677022">保護されたコンテンツの再生をサイトに許可する(推奨)</translation> <translation id="3987993985790029246">リンクのコピー</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">タイトル</translation> <translation id="4008040567710660924">特定のサイトの Cookie を許可します。</translation> +<translation id="4046123991198612571">次のトラック</translation> <translation id="4165986682804962316">サイトの設定</translation> <translation id="4226663524361240545">通知を受け取るとデバイスが振動します</translation> <translation id="4242533952199664413">設定を開く</translation> <translation id="4259722352634471385"><ph name="URL" /> へのアクセスがブロックされました</translation> <translation id="4278390842282768270">許可</translation> +<translation id="429312253194641664">サイトでメディアが再生されています</translation> <translation id="4433925000917964731">Google から提供されている軽量版のページ</translation> <translation id="4434045419905280838">ポップアップとリダイレクト</translation> <translation id="445467742685312942">保護されたコンテンツの再生をサイトに許可する</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">デバイスのすべての権限を取り消します</translation> <translation id="4964199952259983386">Chrome に AR の使用を許可するには、<ph name="BEGIN_LINK" />Android の設定<ph name="END_LINK" />でもカメラをオンにしてください。</translation> <translation id="497421865427891073">次に進む</translation> +<translation id="4996978546172906250">共有方法</translation> <translation id="5039804452771397117">許可</translation> <translation id="5048398596102334565">サイトによるモーション センサーへのアクセスを許可する(推奨)</translation> <translation id="5063480226653192405">使用状況</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">削除</translation> <translation id="6697925417670533197">アクティブなダウンロード</translation> <translation id="6746124502594467657">下に移動</translation> +<translation id="6766622839693428701">閉じるには下にスワイプします。</translation> <translation id="6782111308708962316">サードパーティのウェブサイトが Cookie データを保存したり読み取ったりできないようにします</translation> +<translation id="6790428901817661496">再生</translation> <translation id="6818926723028410516">アイテムを選択</translation> <translation id="6864395892908308021">このデバイスでは NFC を読み込めません</translation> <translation id="6910211073230771657">削除済み</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">サイトでカメラが使用されています</translation> <translation id="7817023149356982970">このサイトからログアウトします。</translation> <translation id="7828557259026017104">Cookie は、アクセスしたサイトによって作成されるファイルです。サイトではこのファイルを使用して各ユーザーが行なった設定が記憶されます。2 つ目の「サードパーティの Cookie」は、他のサイト、つまり現在ウェブページに表示されているコンテンツの一部(広告、画像など)を所有しているサイトによって作成されます。</translation> +<translation id="7835852323729233924">再生中のメディア</translation> <translation id="7846076177841592234">選択解除</translation> <translation id="7846621471902887024">すべてのサイトからログアウトします。</translation> <translation id="7882806643839505685">特定のサイトに対して音声の再生を許可します。</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">すべてのローカルデータ(Cookie を含む)を削除して、このウェブサイトに指定したすべての権限をリセットしてもよろしいですか?</translation> <translation id="8007176423574883786">このデバイスに対して無効</translation> <translation id="802154636333426148">ダウンロード エラー</translation> +<translation id="8068648041423924542">証明書を選択できません</translation> <translation id="8087000398470557479"><ph name="DOMAIN_NAME" /> のコンテンツを Google から配信しています。</translation> <translation id="8116925261070264013">ミュート中</translation> <translation id="8131740175452115882">確認</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">サイトでカメラとマイクが使用されています</translation> <translation id="8380167699614421159">このサイトでは煩わしい広告や誤解を招く広告が表示されます</translation> <translation id="8394832520002899662">タップしてサイトに戻る</translation> +<translation id="8425213833346101688">変更</translation> +<translation id="8441146129660941386">後方にシーク再生</translation> <translation id="8447861592752582886">デバイスの許可を取り消します</translation> <translation id="8463851957836045671">サイトは高速です</translation> <translation id="851751545965956758">サイトからデバイスへの接続をブロックする</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">特定のサイトの Cookie をブロックします。</translation> <translation id="8959122750345127698"><ph name="URL" /> にアクセスできません</translation> <translation id="9019902583201351841">保護者により管理されています</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">マイクへのアクセス</translation> <translation id="965817943346481315">煩わしい広告や誤解を招く広告が表示されるサイトの場合にブロック(推奨)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ka.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ka.xtb index 5f457805be7..212372e6c3a 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ka.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ka.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">შემდეგი</translation> <translation id="1242008676835033345"><ph name="WEBSITE_URL" />-ში ჩაშენებული</translation> <translation id="1272079795634619415">შეწყვეტა</translation> +<translation id="1289742167380433257">მონაცემთა მოცულობის დაზოგვის მიზნით, სურათები ოპტიმიზებულია Google-ის მიერ.</translation> <translation id="129382876167171263">ვებსაიტების მიერ შენახული ფაილები აქ გამოჩნდება</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> — <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">საიტი: <ph name="SITE_NAME" /> დამატებულია</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">შეკითხვა საიტებისთვის თქვენი გარემოს 3-განზომილებიანი რუკის შექმნის ან კამერის პოზიციისთვის თვალის მიდევნების დაშვებამდე (რეკომენდებული)</translation> <translation id="2212565012507486665">ქუქი-ჩანაწერების დაშვება</translation> <translation id="2289270750774289114">საიტების მიერ ახლომდებარე Bluetooth მოწყობილობების აღმოჩენის მოთხოვნა (რეკომენდებული)</translation> +<translation id="2315043854645842844">კლიენტის სერტიფიკატების არჩევა არ არის მხარდაჭერილი ოპერაციული სისტემის მიერ.</translation> <translation id="2359808026110333948">გაგრძელება</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> მბაიტი</translation> <translation id="2434158240863470628">ჩამოტვირთვა დასრულდა: <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">დაკოპირდა</translation> <translation id="2822354292072154809">ნამდვილად გსურთ, საიტის ყველა ნებართვის გადაყენება <ph name="CHOSEN_OBJECT_NAME" />-ისთვის?</translation> <translation id="2870560284913253234">საიტი</translation> +<translation id="2874939134665556319">წინა ჩანაწერი</translation> <translation id="2910701580606108292">შეკითხვა საიტებისთვის დაცული კონტენტის დაკვრის დაშვებამდე</translation> <translation id="2913331724188855103">საშუალებას აძლევს საიტებს შეინახონ და გაეცნონ ქუქი ფაილებს (რეკომენდირებული)</translation> <translation id="2968755619301702150">სერტიფიკატთა მაჩვენებელი</translation> <translation id="300526633675317032">ეს მოქმედება მთლიანად გაასუფთავებს ვებსაიტების მეხსიერებას (სულ: <ph name="SIZE_IN_KB" />).</translation> +<translation id="301521992641321250">დაბლოკილია ავტომატურად</translation> <translation id="3115898365077584848">ინფორმაციის ჩვენება</translation> <translation id="3123473560110926937">დაბლოკილია ზოგიერთ საიტზე</translation> <translation id="3190152372525844641">Chrome-ისთვის ნებართვების გააქტიურება <ph name="BEGIN_LINK" />Android-ის პარამეტრებში<ph name="END_LINK" /> შეგიძლიათ.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">ფონური სინქრონიზაცია</translation> <translation id="3822502789641063741">გასუფთავდეს საიტების მეხსიერება?</translation> <translation id="385051799172605136">უკან</translation> +<translation id="3859306556332390985">წინ ძიება</translation> <translation id="3955193568934677022">ვებსაიტებისთვის დაცული კონტენტის დაკვრის დაშვება (რეკომენდებული)</translation> <translation id="3987993985790029246">ბმულის კოპირება</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">სათაური</translation> <translation id="4008040567710660924">ქუქი-ჩანაწერების დაშვება კონკრეტული საიტისთვის.</translation> +<translation id="4046123991198612571">შემდეგი ჩანაწერი</translation> <translation id="4165986682804962316">საიტის პარამეტრები</translation> <translation id="4226663524361240545">შეტყობინებებმა შეიძლება მოწყობილობის ვიბრაცია გამოიწვიოს</translation> <translation id="4242533952199664413">პარამეტრების გახსნა</translation> <translation id="4259722352634471385">ნავიგაცია დაბლოკილია: <ph name="URL" /></translation> <translation id="4278390842282768270">დაშვებულია</translation> +<translation id="429312253194641664">საიტზე გაშვებულია მედია-კონტენტი</translation> <translation id="4433925000917964731">გვერდის Lite ვერსიას უზრუნველყოფს Google</translation> <translation id="4434045419905280838">ამომხ. ფანჯრები/გადამისამართება</translation> <translation id="445467742685312942">საიტებისთვის დაცული კონტენტის დაკვრის დაშვება</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">მოწყობილობისთვის ყველა ნებართვის გაუქმება</translation> <translation id="4964199952259983386">Chrome-მა AR რომ გამოიყენოს, საჭიროა კამერის ჩართვაც <ph name="BEGIN_LINK" />Android-ის პარამეტრებიდან<ph name="END_LINK" />.</translation> <translation id="497421865427891073">გადასვლა წინ</translation> +<translation id="4996978546172906250">გაზიარების პროგრამა</translation> <translation id="5039804452771397117">დაშვება</translation> <translation id="5048398596102334565">საიტებისთვის მოძრაობის სენსორებზე წვდომის დაშვება (რეკომენდებული)</translation> <translation id="5063480226653192405">გამოყენება</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">გასუფთავება</translation> <translation id="6697925417670533197">მიმდინარე ჩამოტვირთვები</translation> <translation id="6746124502594467657">გადაადგილება ქვემოთ</translation> +<translation id="6766622839693428701">დასახურად გადაფურცლეთ ქვემოთ.</translation> <translation id="6782111308708962316">მესამე მხარის ვებსაიტებისთვის ქუქი-ჩანაწერების მონაცემების შენახვისა და წაკითხვის აკრძალვა</translation> +<translation id="6790428901817661496">დაკვრა</translation> <translation id="6818926723028410516">აირჩიეთ ერთეულები</translation> <translation id="6864395892908308021">NFC მხარდაუჭერელია ამ მოწყობილობის მიერ</translation> <translation id="6910211073230771657">წაშლილი</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">ეს საიტი იყენებს თქვენს კამერას</translation> <translation id="7817023149356982970">თქვენ გამოხვალთ ამ საიტიდან.</translation> <translation id="7828557259026017104">ქუქი-ჩანაწერები თქვენ მიერ მონახულებული ვებსაიტების მიერ შექმნილი ფაილებია. მათი მეშვეობით საიტები თქვენ მიერ არჩეულ პარამეტრებს იმახსოვრებს. მესამე მხარის ქუქი-ჩანაწერები იქმნება სხვა საიტების მიერ. აღნიშნულ საიტებს ეკუთვნის თქვენ მიერ მონახულებულ ვებგვერდზე თქვენთვის ხილული გარკვეული კონტენტი (როგორიცაა რეკლამა ან სურათები).</translation> +<translation id="7835852323729233924">გაშვებული მედია</translation> <translation id="7846076177841592234">შერჩევის გაუქმება</translation> <translation id="7846621471902887024">თქვენ გამოხვალთ ყველა საიტიდან.</translation> <translation id="7882806643839505685">ხმის დაშვება კონკრეტული საიტისთვის.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">დარწმუნებული ხართ, რომ გსურთ ყველა ადგილობრივი მონაცემების წაშლა, მათ შორის ქუქი ფაილების, და ამ გვერდისათვის ყველა ნებართვების აღდგენა?</translation> <translation id="8007176423574883786">გამორთულია ამ მოწყობილობისთვის</translation> <translation id="802154636333426148">ჩამოტვირთვა ვერ მოხერხდა</translation> +<translation id="8068648041423924542">სერტიფიკატის არჩევა შეუძლებელია.</translation> <translation id="8087000398470557479">კონტენტის წყაროა: <ph name="DOMAIN_NAME" />. მიღებულია Google-ის მეშვეობით.</translation> <translation id="8116925261070264013">დადუმებული</translation> <translation id="8131740175452115882">დაადასტურება</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">ეს საიტი იყენებს თქვენს კამერასა და მიკროფონს</translation> <translation id="8380167699614421159">ამ საიტზე ნაჩვენებია მომაბეზრებელი ან შეცდომაში შემყვანი რეკლამა</translation> <translation id="8394832520002899662">შეეხეთ საიტზე დასაბრუნებლად</translation> +<translation id="8425213833346101688">შეცვლა</translation> +<translation id="8441146129660941386">უკან ძიება</translation> <translation id="8447861592752582886">მოწყობილობაზე წვდომის ნებართვის გაუქმება</translation> <translation id="8463851957836045671">საიტი სწრაფია</translation> <translation id="851751545965956758">საიტებისთვის მოწყობილობებთან დაკავშირების აკრძალვა</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">ქუქი-ჩანაწერების დაბლოკვა კონკრეტული საიტისთვის.</translation> <translation id="8959122750345127698">ნავიგაცია მიუწვდომელია: <ph name="URL" /></translation> <translation id="9019902583201351841">იმართება თქვენი მშობლების მიერ</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">თქვენი მიკროფონი ხელმისაწვდომია</translation> <translation id="965817943346481315">დაბლოკვა, თუ საიტი აჩვენებს მომაბეზრებელ ან შეცდომაში შემყვან რეკლამას (რეკომენდებული)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_kk.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_kk.xtb index 60a0afdba20..7c37fd68b4c 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_kk.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_kk.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Келесі</translation> <translation id="1242008676835033345"><ph name="WEBSITE_URL" /> мекенжайына ендірілген</translation> <translation id="1272079795634619415">Тоқтату</translation> +<translation id="1289742167380433257">Деректеріңізді сақтау үшін бұл беттің суреттері Google арқылы оңтайландырылды.</translation> <translation id="129382876167171263">Веб-сайттар арқылы сақталған файлдар осында көрсетіледі.</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> – <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676"><ph name="SITE_NAME" /> сайты қосылды</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Cайттарға айналаңыздың 3D картасын жасауға немесе камераңыздың орнын бақылауға рұқсат беру алдында сізден сұраy (ұсынылады)</translation> <translation id="2212565012507486665">Cookie файлдарына рұқсат беру</translation> <translation id="2289270750774289114">Сайт маңайдағы Bluetooth құрылғыларын анықтағысы келген кезде, рұқсат сұралсын (ұсынылады).</translation> +<translation id="2315043854645842844">Операциялық жүйе клиенттік сертификатты таңдауға қолдау көрсетпейді.</translation> <translation id="2359808026110333948">Жалғастыру</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> МБ</translation> <translation id="2434158240863470628"><ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /> жүктеп алынды</translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Көшірілген</translation> <translation id="2822354292072154809"><ph name="CHOSEN_OBJECT_NAME" /> үшін барлық сайт рұқсаттары шынымен бастапқы күйіне қайтарылсын ба?</translation> <translation id="2870560284913253234">Сайт</translation> +<translation id="2874939134665556319">Алдыңғы аудиотрек</translation> <translation id="2910701580606108292">Қорғалған мазмұнды ойнатуға рұқсат етпес бұрын сұрау</translation> <translation id="2913331724188855103">Сайттарға cookie деректерін сақтауға және оқуға рұқсат беру (ұсынылған)</translation> <translation id="2968755619301702150">Сертификат көру құралы</translation> <translation id="300526633675317032">Вебсайттың барлық деректері жойылады (<ph name="SIZE_IN_KB" />).</translation> +<translation id="301521992641321250">Автоматты түрде бөгелген</translation> <translation id="3115898365077584848">Ақпаратты көрсету</translation> <translation id="3123473560110926937">Кейбір сайттарда тыйым салынған</translation> <translation id="3190152372525844641"><ph name="BEGIN_LINK" />Android параметрлері<ph name="END_LINK" /> ішінен Chrome үшін рұқсаттар қосыңыз.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Фондық синхрондау</translation> <translation id="3822502789641063741">Сайт деректерін өшіру керек пе?</translation> <translation id="385051799172605136">Артқа</translation> +<translation id="3859306556332390985">Алға</translation> <translation id="3955193568934677022">Сайттарға қорғалған мазмұнды ойнатуға рұқсат беру (ұсынылады)</translation> <translation id="3987993985790029246">Сілтемені көшіру</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> <translation id="4002066346123236978">Тақырып</translation> <translation id="4008040567710660924">Белгілі бір сайт үшін cookie файлдарына рұқсат беріңіз.</translation> +<translation id="4046123991198612571">Келесі аудиотрек</translation> <translation id="4165986682804962316">Сайт параметрлері</translation> <translation id="4226663524361240545">Хабарландыру келіп түскенде, құрылғы дірілдейді</translation> <translation id="4242533952199664413">Параметрлерді ашу</translation> <translation id="4259722352634471385">Навигация тыйылған: <ph name="URL" /></translation> <translation id="4278390842282768270">Рұқсат етілген</translation> +<translation id="429312253194641664">Сайтта мультимедиа ойнатылуда</translation> <translation id="4433925000917964731">Google бетті Lite нұсқасында ұсынды</translation> <translation id="4434045419905280838">Қалқымалы терезе және бағыттау</translation> <translation id="445467742685312942">Сайттарға қорғалған мазмұнды ойнатуға рұқсат беру</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Құрылғыға арналған барлық рұқсаттардың күші жойылсын.</translation> <translation id="4964199952259983386">Chrome браузеріне AR режимін пайдалануға рұқсат ету үшін <ph name="BEGIN_LINK" />Android параметрлерінен<ph name="END_LINK" /> камераны да қосыңыз.</translation> <translation id="497421865427891073">Алға өту</translation> +<translation id="4996978546172906250">Бөлісу</translation> <translation id="5039804452771397117">Рұқсат беру</translation> <translation id="5048398596102334565">Сайттардың қозғалыс датчиктеріне кіруіне рұқсат ету (ұсынылады)</translation> <translation id="5063480226653192405">Пайдалану</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Тазалау</translation> <translation id="6697925417670533197">Жүктеп алынып жатқандар</translation> <translation id="6746124502594467657">Төмен қарай жылжыту</translation> +<translation id="6766622839693428701">Жабу үшін төмен сырғытыңыз.</translation> <translation id="6782111308708962316">Үшінші тараптық вебсайттардың cookie деректерін сақтауына және оқуына жол бермеу</translation> +<translation id="6790428901817661496">Ойнату</translation> <translation id="6818926723028410516">Элементтерді таңдаңыз</translation> <translation id="6864395892908308021">Бұл құрылғы NFC сигналын оқи алмайды</translation> <translation id="6910211073230771657">Жойылды</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Сайт камераны пайдаланып жатыр.</translation> <translation id="7817023149356982970">Сіз бұл сайтта есептік жазбадан шығарыласыз.</translation> <translation id="7828557259026017104">Cookie файлдары сайттарға кірген кезде жасалады. Сайттар оларды параметрлер есте сақталуы үшін пайдаланады. Үшінші тараптың cookie файлдары басқа сайттарда жасалады. Бұл сайттарда сіз кірген сайттың мазмұны (мысалы, жарнамалар немесе суреттер) болады.</translation> +<translation id="7835852323729233924">Медиамазмұн ойнату</translation> <translation id="7846076177841592234">Таңдаудан бас тарту</translation> <translation id="7846621471902887024">Сіз барлық сайттардағы есептік жазбадан шығарыласыз.</translation> <translation id="7882806643839505685">Белгілі бір сайтта дыбыстың шығуына рұқсат ету.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Cookie файлдарын қоса, барлық жергілікті деректерді өшіруді және осы веб-сайтқа арналған барлық рұқсаттарды қалпына келтіруді қалайсыз ба?</translation> <translation id="8007176423574883786">Осы құрылғы үшін өшірілді</translation> <translation id="802154636333426148">Жүктеу сәтсіз аяқталды</translation> +<translation id="8068648041423924542">Сертификатты таңдау мүмкін емес.</translation> <translation id="8087000398470557479">Бұл мазмұн Google ұсынған <ph name="DOMAIN_NAME" /> доменінен алынған.</translation> <translation id="8116925261070264013">Дыбысы өшірулі</translation> <translation id="8131740175452115882">Растау</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Сайт камера мен микрофонды пайдаланып жатыр.</translation> <translation id="8380167699614421159">Бұл сайтта мазалайтын немесе жалған ақпаратты жарнамалар көрсетіледі</translation> <translation id="8394832520002899662">Сайтқа оралу үшін түртіңіз.</translation> +<translation id="8425213833346101688">Өзгерту</translation> +<translation id="8441146129660941386">Артқа</translation> <translation id="8447861592752582886">Құрылғыға кіру рұқсатының күшін жою</translation> <translation id="8463851957836045671">Бұл сайт жылдам.</translation> <translation id="851751545965956758">Сайттардың құрылғыға жалғануына тыйым салу</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Белгілі бір сайт үшін cookie файлдарына тыйым салыңыз.</translation> <translation id="8959122750345127698"><ph name="URL" /> мекенжайына өту мүмкін емес</translation> <translation id="9019902583201351841">Ата-аналар басқарады</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Микрофонды пайдалану мүмкіндігі</translation> <translation id="965817943346481315">Сайт мазалайтын немесе жалған ақпаратты жарнамалар көрсеткен жағдайда бөгеу (ұсынылады)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_km.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_km.xtb index da0f98e5ac0..944a179ffa8 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_km.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_km.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">បន្ទាប់</translation> <translation id="1242008676835033345">បានបង្កប់នៅលើ <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">ឈប់</translation> +<translation id="1289742167380433257">ដើម្បីសន្សំសំចៃទិន្នន័យឱ្យអ្នក រូបភាពរបស់ទំព័រនេះត្រូវបានបង្កើនគុណភាពដោយ Google។</translation> <translation id="129382876167171263">ឯកសារដែលបានរក្សាទុកដោយគេហទំព័របង្ហាញនៅទីនេះ</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> - <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">គេហទំព័រ <ph name="SITE_NAME" /> ត្រូវបានបន្ថែម</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">សួរមុនពេលអនុញ្ញាតឱ្យគេហទំព័របង្កើតផែនទី 3D នៃមជ្ឈដ្ឋានជុំវិញរបស់អ្នក ឬតាមដានទីតាំងកាមេរ៉ា (បានណែនាំ)</translation> <translation id="2212565012507486665">អនុញ្ញាតខូគី</translation> <translation id="2289270750774289114">សួរនៅពេលគេហទំព័រចង់ស្វែងរកឧបករណ៍ប៊្លូធូសដែលនៅជិត (បានណែនាំ)</translation> +<translation id="2315043854645842844">ការជ្រើសរើសវិញ្ញាបនបត្រសម្រាប់ម៉ាស៊ីនកូនមិនគាំទ្រដោយប្រព័ន្ធដំណើរការនេះទេ។</translation> <translation id="2359808026110333948">បន្ត</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">ការទាញយកបានបញ្ចប់ <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">បានថតចម្លង</translation> <translation id="2822354292072154809">តើអ្នកប្រាកដថាចង់កំណត់ការអនុញ្ញាតគេហទំព័រទាំងអស់ឡើងវិញសម្រាប់ <ph name="CHOSEN_OBJECT_NAME" /> ដែរទេ?</translation> <translation id="2870560284913253234">គេហទំព័រ</translation> +<translation id="2874939134665556319">បទមុន</translation> <translation id="2910701580606108292">សួរមុនពេលអនុញ្ញតឱ្យគេហទំព័រលេងខ្លឹមសារដែលមានការការពារ</translation> <translation id="2913331724188855103">អនុញ្ញាតឲ្យគេហទំព័ររក្សាទុក និងអានទិន្នន័យខុកឃី (បានណែនាំ)</translation> <translation id="2968755619301702150">កម្មវិធីមើលវិញ្ញាបនប័ត្រ</translation> <translation id="300526633675317032">វានឹងជម្រះ <ph name="SIZE_IN_KB" /> ទាំងស្រុងនៃទំហំផ្ទុកគេហទំព័រ</translation> +<translation id="301521992641321250">បានទប់ស្កាត់ដោយស្វ័យប្រវត្តិ</translation> <translation id="3115898365077584848">បង្ហាញព័ត៌មាន</translation> <translation id="3123473560110926937">បានទប់ស្កាត់នៅលើគេហទំព័រមួយចំនួន</translation> <translation id="3190152372525844641">បើកសិទ្ធិអនុញ្ញាតសម្រាប់ Chrome នៅក្នុង <ph name="BEGIN_LINK" />ការកំណត់ Android<ph name="END_LINK" />។</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">សមកាលកម្មផ្ទៃខាងក្រោយ</translation> <translation id="3822502789641063741">ជម្រះទំហំផ្ទុកគេហទំព័រឬ?</translation> <translation id="385051799172605136">ថយក្រោយ</translation> +<translation id="3859306556332390985">ស្វែងរកទៅមុខ</translation> <translation id="3955193568934677022">អនុញ្ញាតឲ្យទំព័រចាក់មាតិកាដែលមានការការពារ (ត្រូវបានណែនាំ)</translation> <translation id="3987993985790029246">ចម្លងតំណ</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">ចំណងជើង</translation> <translation id="4008040567710660924">អនុញ្ញាតខូគីសម្រាប់គេហទំព័រជាក់លាក់។</translation> +<translation id="4046123991198612571">បទបន្ទាប់</translation> <translation id="4165986682804962316">ការកំណត់គេហទំព័រ</translation> <translation id="4226663524361240545">ការជូនដំណឹងអាចនឹងធ្វើឲ្យឧបករណ៍ញ័រ</translation> <translation id="4242533952199664413">បើកការកំណត់</translation> <translation id="4259722352634471385">ការរុករកត្រូវបានរារាំង៖ <ph name="URL" /></translation> <translation id="4278390842282768270">បានអនុញ្ញាត</translation> +<translation id="429312253194641664">គេហទំព័រកំពុងចាក់មេឌៀ</translation> <translation id="4433925000917964731">ទំព័រស្រាលដែលផ្ដល់ដោយ Google</translation> <translation id="4434045419905280838">ផ្ទាំងផុស និងការបញ្ជូនបន្ត</translation> <translation id="445467742685312942">អនុញ្ញាតឱ្យគេហទំព័រចាក់ខ្លឹមសារដែលមានការការពារ</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">ដកការអនុញ្ញាតទាំងអស់សម្រាប់ឧបករណ៍</translation> <translation id="4964199952259983386">ដើម្បីអនុញ្ញាតឱ្យ Chrome ប្រើ AR សូមបើកកាមេរ៉ានៅក្នុង<ph name="BEGIN_LINK" />ការកំណត់ Android<ph name="END_LINK" /> ផងដែរ។</translation> <translation id="497421865427891073">ទៅមុខ</translation> +<translation id="4996978546172906250">ចែករំលែកតាមរយៈ</translation> <translation id="5039804452771397117">អនុញ្ញាត</translation> <translation id="5048398596102334565">អនុញ្ញាតឱ្យគេហទំព័រចូលប្រើឧបករណ៍ចាប់ចលនា (បានណែនាំ)</translation> <translation id="5063480226653192405">ការប្រើប្រាស់</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">ជម្រះ</translation> <translation id="6697925417670533197">ការទាញយកដែលកំពុងដំណើរការ</translation> <translation id="6746124502594467657">រំកិលចុះ</translation> +<translation id="6766622839693428701">អូសចុះក្រោមដើម្បីបិទ។</translation> <translation id="6782111308708962316">ទប់ស្កាត់គេហទំព័រភាគីទីបីមិនឲ្យរក្សាទុក និងអានទិន្នន័យខូគី</translation> +<translation id="6790428901817661496">លេង</translation> <translation id="6818926723028410516">ជ្រើសរើសធាតុ</translation> <translation id="6864395892908308021">ឧបករណ៍នេះមិនអាចអាន NFC បានទេ</translation> <translation id="6910211073230771657">បានលុប</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">គេហទំព័រមួយកំពុងប្រើប្រាស់កាមេរ៉ារបស់អ្នក</translation> <translation id="7817023149356982970">អ្នកនឹងត្រូវនាំចេញពីគេហទំព័រនេះ។</translation> <translation id="7828557259026017104">ខូគីជាឯកសារដែលបង្កើតដោយគេហទំព័រដែលអ្នកចូលមើល។ គេហទំព័រប្រើខូគីទាំងនេះ ដើម្បីចងចាំចំណូលចិត្តរបស់អ្នក។ ខូគីភាគីទីបីបង្កើតដោយគេហទំព័រផ្សេងទៀត។ គេហទំព័រទាំងនេះគឺជាម្ចាស់នៃខ្លឹមសារមួយចំនួន ដូចជាការផ្សាយពាណិជ្ជកម្ម ឬរូបភាព ដែលអ្នកឃើញនៅលើទំព័របណ្ដាញដែលអ្នកចូលមើលជាដើម។</translation> +<translation id="7835852323729233924">ការចាក់មេឌៀ</translation> <translation id="7846076177841592234">បោះបង់ការជ្រើសរើស</translation> <translation id="7846621471902887024">អ្នកនឹងត្រូវនាំចេញពីគេហទំព័រទាំងអស់។</translation> <translation id="7882806643839505685">អនុញ្ញាតសំឡេងសម្រាប់ទំព័រជាក់លាក់។</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">តើអ្នកប្រាកដទេដែលចង់សម្អាតទិន្នន័យមូលដ្ឋានទាំងអស់រាប់ទាំងខុឃី ហើយកំណត់ការអនុញ្ញាតទាំងឡាយសម្រាប់គេហទំព័រនេះឡើងវិញនោះ?</translation> <translation id="8007176423574883786">បានបិទសម្រាប់ឧបករណ៍នេះ</translation> <translation id="802154636333426148">បានបរាជ័យក្នុងការទាញយក</translation> +<translation id="8068648041423924542">មិនអាចជ្រើសរើសវិញ្ញាបនបត្រទេ</translation> <translation id="8087000398470557479">មាតិកានេះបានពី <ph name="DOMAIN_NAME" /> ដែលចែកចាយដោយ Google។</translation> <translation id="8116925261070264013">បានបិទសំឡេង</translation> <translation id="8131740175452115882">អះអាង</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">គេហទំព័រមួយកំពុងប្រើប្រាស់កាមេរ៉ា និងមីក្រូហ្វូនរបស់អ្នក</translation> <translation id="8380167699614421159">គេហទំព័រនេះបង្ហាញការផ្សាយពាណិជ្ជកម្មដែលនាំឱ្យយល់ច្រឡំ ឬរំខាន</translation> <translation id="8394832520002899662">ចុចដើម្បីត្រឡប់ទៅគេហទំព័រវិញ</translation> +<translation id="8425213833346101688">ប្តូរ</translation> +<translation id="8441146129660941386">ស្វែងរកថយក្រោយ</translation> <translation id="8447861592752582886">ដកហូតសិទ្ធិអនុញ្ញាតឧបករណ៍</translation> <translation id="8463851957836045671">គេហទំព័រដំណើរការលឿន</translation> <translation id="851751545965956758">ទប់ស្កាត់ទំព័រមិនឱ្យភ្ជាប់ជាមួយឧបករណ៍</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">ទប់ស្កាត់ខូគីសម្រាប់គេហទំព័រជាក់លាក់។</translation> <translation id="8959122750345127698">ការុករកមិនអាចភ្ជាប់បានទេ៖ <ph name="URL" /></translation> <translation id="9019902583201351841">គ្រប់គ្រងដោយឪពុកម្តាយរបស់អ្នក</translation> +<translation id="9074739597929991885">ប៊្លូធូស</translation> <translation id="945632385593298557">ចូលប្រើម៉ៃក្រូហ្វូនរបស់អ្នក</translation> <translation id="965817943346481315">ទប់ស្កាត់ ប្រសិនបើគេហទំព័របង្ហាញការផ្សាយពាណិជ្ជកម្មដែលនាំឱ្យយល់ច្រឡំ ឬរំខាន (បានណែនាំ)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_kn.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_kn.xtb index 4cd93ff8d7e..dc020e32ff3 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_kn.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_kn.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">ಮುಂದೆ</translation> <translation id="1242008676835033345"><ph name="WEBSITE_URL" /> ನಲ್ಲಿ ಎಂಬೆಡ್ ಮಾಡಲಾಗಿದೆ</translation> <translation id="1272079795634619415">ನಿಲ್ಲಿಸಿ</translation> +<translation id="1289742167380433257">ನಿಮ್ಮ ಡೇಟಾವನ್ನು ಉಳಿಸಲು, ಈ ಪುಟದ ಚಿತ್ರಗಳನ್ನು Google ಮೂಲಕ ಆಪ್ಟಿಮೈಸ್ ಮಾಡಲಾಗಿದೆ.</translation> <translation id="129382876167171263">ವೆಬ್ಸೈಟ್ಗಳ ಮೂಲಕ ಉಳಿಸಲಾಗಿರುವ ಫೈಲ್ಗಳು ಇಲ್ಲಿ ಗೋಚರಿಸುತ್ತವೆ</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> - <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676"><ph name="SITE_NAME" /> ಸೈಟ್ ಸೇರಿಸಲಾಗಿದೆ</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">ನಿಮ್ಮ ಸುತ್ತಮುತ್ತಲಿನ 3D ನಕ್ಷೆಗಳನ್ನು ರಚಿಸಲು ಅಥವಾ ಕ್ಯಾಮರಾ ಸ್ಥಿತಿಯನ್ನು ಟ್ರ್ಯಾಕ್ ಮಾಡಲು ಸೈಟ್ಗೆ ಅನುಮತಿಸುವ ಮೊದಲು ಕೇಳಿ (ಶಿಫಾರಸು ಮಾಡಲಾಗಿರುವುದು)</translation> <translation id="2212565012507486665">ಕುಕೀಗಳನ್ನು ಅನುಮತಿಸಿ</translation> <translation id="2289270750774289114">ಸೈಟ್ ಯಾವಾಗ ಸಮೀಪದ ಬ್ಲೂಟೂತ್ ಸಾಧನಗಳನ್ನು ಅನ್ವೇಷಿಸಲು ಬಯಸುತ್ತದೆಯೋ ಆಗ ಕೇಳಿ (ಶಿಫಾರಸು ಮಾಡಲಾಗಿದೆ)</translation> +<translation id="2315043854645842844">ಕ್ಲೈಂಟ್ನ ಪ್ರಮಾಣಪತ್ರ ಆಯ್ಕೆಯನ್ನು ಆಪರೇಟಿಂಗ್ ಸಿಸ್ಟಂನಿಂದ ಬೆಂಬಲಿಸಲಾಗಿಲ್ಲ.</translation> <translation id="2359808026110333948">ಮುಂದುವರೆಸಿ</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">ಡೌನ್ಲೋಡ್ ಪೂರ್ಣಗೊಂಡಿದೆ <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">ನಕಲಿಸಲಾಗಿದೆ</translation> <translation id="2822354292072154809">ನೀವು <ph name="CHOSEN_OBJECT_NAME" /> ಗಾಗಿ ಎಲ್ಲಾ ಸೈಟ್ ಅನುಮತಿಗಳನ್ನು ಖಚಿತವಾಗಿಯೂ ಮರುಹೊಂದಿಸಲು ಬಯಸುತ್ತೀರಾ?</translation> <translation id="2870560284913253234">ಸೈಟ್</translation> +<translation id="2874939134665556319">ಹಿಂದಿನ ಟ್ರ್ಯಾಕ್</translation> <translation id="2910701580606108292">ಸಂರಕ್ಷಿತ ವಿಷಯವನ್ನು ಪ್ಲೇ ಮಾಡಲು ಸೈಟ್ಗಳಿಗೆ ಅನುಮತಿಸುವ ಮೊದಲು ಕೇಳಿ</translation> <translation id="2913331724188855103">ಕುಕೀ ಡೇಟಾವನ್ನು ಉಳಿಸಲು ಮತ್ತು ರೀಡ್ ಮಾಡಲು ಸೈಟ್ಗಳನ್ನು ಅನುಮತಿಸಿ (ಶಿಫಾರಸು ಮಾಡಲಾಗಿದೆ)</translation> <translation id="2968755619301702150">ಪ್ರಮಾಣಪತ್ರ ವೀಕ್ಷಕ</translation> <translation id="300526633675317032">ಇದು ವೆಬ್ಸೈಟ್ ಸಂಗ್ರಹಣೆಯ ಎಲ್ಲಾ <ph name="SIZE_IN_KB" /> ಅನ್ನು ತೆರವುಗೊಳಿಸುತ್ತದೆ.</translation> +<translation id="301521992641321250">ಸ್ವಯಂಚಾಲಿತವಾಗಿ ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ</translation> <translation id="3115898365077584848">ಮಾಹಿತಿಯನ್ನು ತೋರಿಸಿ</translation> <translation id="3123473560110926937">ಕೆಲವು ಸೈಟ್ಗಳಲ್ಲಿ ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ</translation> <translation id="3190152372525844641"><ph name="BEGIN_LINK" />Android ಸೆಟ್ಟಿಂಗ್ಗಳಲ್ಲಿ<ph name="END_LINK" /> Chrome ಗೆ ಅನುಮತಿಗಳನ್ನು ಆನ್ ಮಾಡಿ.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">ಹಿನ್ನೆಲೆ ಸಿಂಕ್</translation> <translation id="3822502789641063741">ಸೈಟ್ ಸಂಗ್ರಹಣೆ ತೆರವುಗೊಳಿಸುವುದೇ?</translation> <translation id="385051799172605136">ಹಿಂದೆ</translation> +<translation id="3859306556332390985">ಮುಂದಕ್ಕೆ ಸೀಕ್ ಮಾಡಿ</translation> <translation id="3955193568934677022">ಸಂರಕ್ಷಿಸಲಾದ ವಿಷಯವನ್ನು ಪ್ಲೇ ಮಾಡಲು ಸೈಟ್ಗಳಿಗೆ ಅನುಮತಿಸಿ (ಶಿಫಾರಸು ಮಾಡಲಾಗಿದೆ)</translation> <translation id="3987993985790029246">ಲಿಂಕ್ ನಕಲಿಸಿ</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">ಶೀರ್ಷಿಕೆ</translation> <translation id="4008040567710660924">ನಿರ್ದಿಷ್ಟ ಸೈಟ್ ಒಂದಕ್ಕೆ ಕುಕೀಗಳನ್ನು ಅನುಮತಿಸಿ.</translation> +<translation id="4046123991198612571">ಮುಂದಿನ ಟ್ರ್ಯಾಕ್</translation> <translation id="4165986682804962316">ಸೈಟ್ ಸೆಟ್ಟಿಂಗ್ಗಳು</translation> <translation id="4226663524361240545">ಪ್ರಕಟಣೆಗಳು ಸಾಧನವನ್ನು ವೈಬ್ರೇಟ್ ಮಾಡಬಹುದು</translation> <translation id="4242533952199664413">ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ತೆರೆ</translation> <translation id="4259722352634471385">ನ್ಯಾವಿಗೇಶನ್ ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ: <ph name="URL" /></translation> <translation id="4278390842282768270">ಅನುಮತಿಸಲಾಗಿದೆ</translation> +<translation id="429312253194641664">ಒಂದು ಸೈಟ್, ಮಾಧ್ಯಮವನ್ನು ಪ್ಲೇ ಮಾಡುತ್ತಿದೆ</translation> <translation id="4433925000917964731">Lite ಪುಟವನ್ನು Google ಒದಗಿಸಿದೆ</translation> <translation id="4434045419905280838">ಪಾಪ್-ಅಪ್ಗಳು ಹಾಗೂ ಮರುನಿರ್ದೇಶನಗಳು</translation> <translation id="445467742685312942">ಸಂರಕ್ಷಿತ ವಿಷಯವನ್ನು ಪ್ಲೇ ಮಾಡಲು ಸೈಟ್ಗಳಿಗೆ ಅನುಮತಿ ನೀಡಿ</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">ಸಾಧನಕ್ಕೆ ನೀಡಿರುವ ಎಲ್ಲಾ ಅನುಮತಿಗಳನ್ನು ಹಿಂಪಡೆಯಿರಿ</translation> <translation id="4964199952259983386">AR ಬಳಸಲು Chrome ಗೆ ಅನುಮತಿ ನೀಡುವುದಕ್ಕಾಗಿ, <ph name="BEGIN_LINK" />Android ಸೆಟ್ಟಿಂಗ್ಗಳಲ್ಲಿ<ph name="END_LINK" /> ಕ್ಯಾಮರಾವನ್ನು ಆನ್ ಮಾಡಿ.</translation> <translation id="497421865427891073">ಮುಂದಕ್ಕೆ ಹೋಗು</translation> +<translation id="4996978546172906250">ಇದರ ಮೂಲಕ ಹಂಚಿ</translation> <translation id="5039804452771397117">ಅನುಮತಿಸಿ</translation> <translation id="5048398596102334565">ಚಲನಾ ಸೆನ್ಸರ್ಗಳನ್ನು ಪ್ರವೇಶಿಸಲು ಸೈಟ್ಗಳಿಗೆ ಅನುಮತಿ ನೀಡಿ (ಶಿಫಾರಸು ಮಾಡಿರುವುದು)</translation> <translation id="5063480226653192405">ಬಳಕೆ</translation> @@ -163,8 +171,10 @@ <translation id="6643016212128521049">ತೆರವುಗೊಳಿಸಿ</translation> <translation id="6697925417670533197">ಸಕ್ರಿಯ ಡೌನ್ಲೋಡ್ಗಳು</translation> <translation id="6746124502594467657">ಕೆಳಗೆ ಸರಿಸು</translation> +<translation id="6766622839693428701">ಮುಚ್ಚಲು ಕೆಳಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ.</translation> <translation id="6782111308708962316">ಕುಕೀ ಡೇಟಾವನ್ನು ಮೂರನೇ ವ್ಯಕ್ತಿ ವೆಬ್ಸೈಟ್ಗಳು ಉಳಿಸದಂತೆ ಮತ್ತು ಓದದಂತೆ ತಡೆಯಿರಿ.</translation> +<translation id="6790428901817661496">ಪ್ಲೇ ಮಾಡು</translation> <translation id="6818926723028410516">ಐಟಂಗಳನ್ನು ಆಯ್ಕೆಮಾಡಿ</translation> <translation id="6864395892908308021">ಈ ಸಾಧನವು NFC ಯನ್ನು ಓದಲು ಸಾಧ್ಯವಿಲ್ಲ</translation> <translation id="6910211073230771657">ಅಳಿಸಲಾಗಿದೆ</translation> @@ -198,6 +208,7 @@ <translation id="7804248752222191302">ಒಂದು ಸೈಟ್ ನಿಮ್ಮ ಕ್ಯಾಮರಾವನ್ನು ಬಳಸುತ್ತಿದೆ</translation> <translation id="7817023149356982970">ನಿಮ್ಮನ್ನು ಈ ಸೈಟ್ನಿಂದ ಸೈನ್ ಔಟ್ ಮಾಡಲಾಗುತ್ತದೆ.</translation> <translation id="7828557259026017104">ಕುಕೀಗಳು ಎಂದರೆ ನೀವು ಭೇಟಿ ನೀಡುವ ವೆಬ್ಸೈಟ್ಗಳು ರಚಿಸಿದ ಫೈಲ್ಗಳು. ನಿಮ್ಮ ಆದ್ಯತೆಗಳನ್ನು ನೆನಪಿನಲ್ಲಿಡಲು, ಸೈಟ್ಗಳು ಕುಕೀಗಳನ್ನು ಬಳಸಿಕೊಳ್ಳುತ್ತವೆ. ಥರ್ಡ್-ಪಾರ್ಟಿ ಕುಕೀಗಳನ್ನು ಇತರ ಸೈಟ್ಗಳಿಂದ ರಚಿಸಲಾಗಿದೆ. ನೀವು ಭೇಟಿ ನೀಡುವ ವೆಬ್ಪುಟ ನೀವು ನೋಡುವ ಜಾಹೀರಾತುಗಳು ಅಥವಾ ಚಿತ್ರಗಳಂತಹ ಕೆಲವು ರೀತಿಯ ವಿಷಯವನ್ನು, ಈ ಸೈಟ್ಗಳು ಮಾಲೀಕತ್ವವನ್ನು ಹೊಂದಿವೆ.</translation> +<translation id="7835852323729233924">ಮೀಡಿಯಾ ಪ್ಲೇ ಆಗುತ್ತಿದೆ</translation> <translation id="7846076177841592234">ಆಯ್ಕೆ ರದ್ದುಮಾಡಿ</translation> <translation id="7846621471902887024">ಎಲ್ಲಾ ಸೈಟ್ಗಳಿಂದ ನಿಮ್ಮನ್ನು ಸೈನ್ ಔಟ್ ಮಾಡಲಾಗುತ್ತದೆ.</translation> <translation id="7882806643839505685">ನಿರ್ದಿಷ್ಟ ಸೈಟ್ನ ಧ್ವನಿಯನ್ನು ಅನುಮತಿಸಿ.</translation> @@ -205,6 +216,7 @@ <translation id="7999064672810608036">ಕುಕೀಗಳು ಸೇರಿದಂತೆ, ಸ್ಥಳೀಯ ಎಲ್ಲಾ ಡೇಟಾವನ್ನು ಅಳಿಸಲು ಮತ್ತು ಈ ವೆಬ್ಸೈಟ್ಗೆ ಎಲ್ಲಾ ಅನುಮತಿಗಳನ್ನು ಮರುಹೊಂದಿಸಲು ನೀವು ಖಚಿತವಾಗಿ ಬಯಸುವಿರಾ?</translation> <translation id="8007176423574883786">ಈ ಸಾಧನಕ್ಕೆ ಆಫ್ ಮಾಡಲಾಗಿದೆ</translation> <translation id="802154636333426148">ಡೌನ್ಲೋಡ್ ವಿಫಲಗೊಂಡಿದೆ</translation> +<translation id="8068648041423924542">ಪ್ರಮಾಣಪತ್ರವನ್ನು ಆಯ್ಕೆಮಾಡಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ.</translation> <translation id="8087000398470557479"><ph name="DOMAIN_NAME" /> ಡೊಮೇನ್ನ ಈ ವಿಷಯವನ್ನು Google ನಿಂದ ವಿತರಿಸಲಾಗಿದೆ.</translation> <translation id="8116925261070264013">ಮ್ಯೂಟ್ ಆಗಿರುವುದು</translation> <translation id="8131740175452115882">ದೃಢೀಕರಿಸು</translation> @@ -217,6 +229,8 @@ <translation id="83792324527827022">ಒಂದು ಸೈಟ್ ನಿಮ್ಮ ಕ್ಯಾಮರಾ ಹಾಗೂ ಮೈಕ್ರೊಫೋನ್ ಅನ್ನು ಬಳಸುತ್ತಿದೆ</translation> <translation id="8380167699614421159">ಅತಿಕ್ರಮಣಕಾರಿಯಾಗಿರುವ ಅಥವಾ ತಪ್ಪುದಾರಿಗೆಳೆಯುವ ಜಾಹೀರಾತುಗಳನ್ನು ಈ ಸೈಟ್ ತೋರಿಸುತ್ತದೆ</translation> <translation id="8394832520002899662">ಸೈಟ್ಗೆ ಮರಳಲು ಟ್ಯಾಪ್ ಮಾಡಿ</translation> +<translation id="8425213833346101688">ಬದಲಿಸಿ</translation> +<translation id="8441146129660941386">ಹಿಂದಕ್ಕೆ ಸೀಕ್ ಮಾಡಿ</translation> <translation id="8447861592752582886">ಸಾಧನ ಅನುಮತಿಯನ್ನು ಹಿಂತೆಗೆದುಕೊಳ್ಳಿ</translation> <translation id="8463851957836045671">ಸೈಟ್ ವೇಗವಾಗಿದೆ</translation> <translation id="851751545965956758">ಸಾಧನಗಳಿಗೆ ಸಂಪರ್ಕಿಸದಂತೆ, ಸೈಟ್ಗಳನ್ನು ನಿರ್ಬಂಧಿಸಿ</translation> @@ -237,6 +251,7 @@ <translation id="8958424370300090006">ನಿರ್ದಿಷ್ಟ ಸೈಟ್ ಒಂದಕ್ಕೆ ಕುಕೀಗಳನ್ನು ನಿರ್ಬಂಧಿಸಿ.</translation> <translation id="8959122750345127698">ನ್ಯಾವಿಗೇಶನ್ ತಲುಪಲಾಗುವುದಿಲ್ಲ: <ph name="URL" /></translation> <translation id="9019902583201351841">ನಿಮ್ಮ ಪೋಷಕರು ನಿರ್ವಹಿಸುತ್ತಿದ್ದಾರೆ</translation> +<translation id="9074739597929991885">ಬ್ಲೂಟೂತ್</translation> <translation id="945632385593298557">ನಿಮ್ಮ ಮೈಕ್ರೋಫೋನ್ ಪ್ರವೇಶಿಸಿ</translation> <translation id="965817943346481315">ಅತಿಕ್ರಮಣಕಾರಿಯಾಗಿರುವ ಅಥವಾ ತಪ್ಪುದಾರಿಗೆಳೆಯುವ ಜಾಹೀರಾತುಗಳನ್ನು ಸೈಟ್ ತೋರಿಸಿದರೆ ಅದನ್ನು ನಿರ್ಬಂಧಿಸಿ (ಶಿಫಾರಸು ಮಾಡಲಾಗಿದೆ)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ko.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ko.xtb index 741be12d77b..403f48f88cc 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ko.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ko.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">다음</translation> <translation id="1242008676835033345"><ph name="WEBSITE_URL" />에 삽입됨</translation> <translation id="1272079795634619415">중지</translation> +<translation id="1289742167380433257">데이터를 저장하기 위해 Google에서 이 페이지의 이미지를 최적화했습니다.</translation> <translation id="129382876167171263">웹사이트에서 저장한 파일이 여기에 표시됩니다.</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> - <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676"><ph name="SITE_NAME" /> 사이트 추가됨</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">사이트에서 주변 환경의 3D 지도를 생성하거나 카메라 위치를 추적하도록 허용하기 전에 확인(권장)</translation> <translation id="2212565012507486665">쿠키 허용</translation> <translation id="2289270750774289114">사이트가 주변 블루투스 기기를 조회하려고 할 때 확인(권장)</translation> +<translation id="2315043854645842844">클라이언트측 인증서 선택이 운영체제에서 지원되지 않습니다.</translation> <translation id="2359808026110333948">계속</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" />MB</translation> <translation id="2434158240863470628">다운로드 완료: <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">복사됨</translation> <translation id="2822354292072154809"><ph name="CHOSEN_OBJECT_NAME" />의 모든 사이트 권한을 재설정하시겠습니까?</translation> <translation id="2870560284913253234">사이트</translation> +<translation id="2874939134665556319">이전 트랙</translation> <translation id="2910701580606108292">사이트에서 보호된 콘텐츠를 재생하도록 허용하기 전에 확인</translation> <translation id="2913331724188855103">사이트에서 쿠키 데이터를 저장하고 읽도록 허용(권장)</translation> <translation id="2968755619301702150">인증서 뷰어</translation> <translation id="300526633675317032">웹사이트 저장공간 <ph name="SIZE_IN_KB" />가 모두 삭제됩니다.</translation> +<translation id="301521992641321250">자동으로 차단됨</translation> <translation id="3115898365077584848">정보 표시</translation> <translation id="3123473560110926937">일부 사이트에서 차단됨</translation> <translation id="3190152372525844641"><ph name="BEGIN_LINK" />Android 설정<ph name="END_LINK" />에서 Chrome 관련 권한을 설정합니다.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">백그라운드 동기화</translation> <translation id="3822502789641063741">사이트 저장공간을 삭제하시겠습니까?</translation> <translation id="385051799172605136">뒤로</translation> +<translation id="3859306556332390985">앞으로 탐색</translation> <translation id="3955193568934677022">사이트에서 보호된 콘텐츠를 재생하도록 허용(권장)</translation> <translation id="3987993985790029246">링크 복사</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> <translation id="4002066346123236978">제목</translation> <translation id="4008040567710660924">특정 사이트의 쿠키를 허용합니다.</translation> +<translation id="4046123991198612571">다음 트랙</translation> <translation id="4165986682804962316">사이트 설정</translation> <translation id="4226663524361240545">알림이 있으면 진동이 울릴 수도 있습니다.</translation> <translation id="4242533952199664413">설정 열기</translation> <translation id="4259722352634471385">탐색이 차단됨: <ph name="URL" /></translation> <translation id="4278390842282768270">허용</translation> +<translation id="429312253194641664">사이트에서 미디어 재생 중</translation> <translation id="4433925000917964731">Google에서 제공하는 라이트 페이지</translation> <translation id="4434045419905280838">팝업 및 리디렉션</translation> <translation id="445467742685312942">사이트에서 보호된 콘텐츠를 재생하도록 허용</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">기기에서 모든 권한을 취소합니다.</translation> <translation id="4964199952259983386">Chrome에서 AR을 사용하려면 <ph name="BEGIN_LINK" />Android 설정<ph name="END_LINK" />에서도 카메라를 사용 설정합니다.</translation> <translation id="497421865427891073">앞으로 이동</translation> +<translation id="4996978546172906250">공유 방법</translation> <translation id="5039804452771397117">허용</translation> <translation id="5048398596102334565">사이트의 움직임 감지 센서 액세스 허용(권장)</translation> <translation id="5063480226653192405">사용</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">삭제</translation> <translation id="6697925417670533197">진행 중인 다운로드</translation> <translation id="6746124502594467657">아래로 이동</translation> +<translation id="6766622839693428701">닫으려면 아래로 스와이프하세요.</translation> <translation id="6782111308708962316">타사 웹사이트에서 쿠키 데이터를 저장하거나 읽을 수 없도록 방지</translation> +<translation id="6790428901817661496">재생</translation> <translation id="6818926723028410516">항목 선택</translation> <translation id="6864395892908308021">기기에서 NFC를 읽을 수 없음</translation> <translation id="6910211073230771657">삭제됨</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">사이트에서 카메라 사용 중</translation> <translation id="7817023149356982970">이 사이트에서 로그아웃됩니다.</translation> <translation id="7828557259026017104">쿠키는 방문한 웹사이트에서 생성된 파일로, 사이트에서 사용자의 설정을 기억하기 위해 사용합니다. 타사 쿠키는 다른 사이트, 즉 광고나 이미지 등 방문하는 웹페이지에 표시되는 일부 콘텐츠를 소유하는 사이트에 의해 생성됩니다.</translation> +<translation id="7835852323729233924">재생 중인 미디어</translation> <translation id="7846076177841592234">선택 취소</translation> <translation id="7846621471902887024">모든 사이트에서 로그아웃됩니다.</translation> <translation id="7882806643839505685">특정 사이트에서 소리를 재생하도록 허용합니다.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">쿠키를 포함하여 이 웹사이트의 모든 로컬 데이터를 삭제하고 모든 권한을 재설정하시겠습니까?</translation> <translation id="8007176423574883786">기기에 대해 사용 중지됨</translation> <translation id="802154636333426148">다운로드 실패</translation> +<translation id="8068648041423924542">인증서를 선택할 수 없습니다.</translation> <translation id="8087000398470557479">이 콘텐츠의 출처는 Google에서 제공하는 <ph name="DOMAIN_NAME" />입니다.</translation> <translation id="8116925261070264013">음소거됨</translation> <translation id="8131740175452115882">확인</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">사이트에서 카메라와 마이크를 사용 중입니다.</translation> <translation id="8380167699614421159">이 사이트에서는 방해가 되거나 사용자를 현혹하는 광고를 표시합니다.</translation> <translation id="8394832520002899662">탭하여 사이트로 돌아가기</translation> +<translation id="8425213833346101688">변경</translation> +<translation id="8441146129660941386">뒤로 탐색</translation> <translation id="8447861592752582886">기기 액세스 권한 취소</translation> <translation id="8463851957836045671">사이트 속도 빠름</translation> <translation id="851751545965956758">사이트에서 기기에 연결하지 못하도록 차단</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">특정 사이트의 쿠키를 차단합니다.</translation> <translation id="8959122750345127698">탐색할 수 없음: <ph name="URL" /></translation> <translation id="9019902583201351841">부모님이 관리합니다.</translation> +<translation id="9074739597929991885">블루투스</translation> <translation id="945632385593298557">마이크에 액세스</translation> <translation id="965817943346481315">사이트에서 방해가 되거나 사용자를 현혹하는 광고를 표시하는 경우 광고 차단(권장)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ky.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ky.xtb index 51ca8fd3abc..48481112d39 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ky.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ky.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Кийинки</translation> <translation id="1242008676835033345"><ph name="WEBSITE_URL" /> кыналган</translation> <translation id="1272079795634619415">Токтотуу</translation> +<translation id="1289742167380433257">Интернет трафигин үнөмдөө үчүн Google бул барактагы сүрөттөрдү ыңгайлаштырды.</translation> <translation id="129382876167171263">Вебсайттар сактаган файлдар ушул жерде көрүнөт</translation> <translation id="1364532808393826295"><ph name="APP_NAME" />, <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676"><ph name="SITE_NAME" /> сайты кошулду</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Сайттар айланаңыздын 3D картасын түзгөнү же камераңыздын абалын көргөнү жатканда уруксат суралсын (сунушталат)</translation> <translation id="2212565012507486665">Cookies файлдарына уруксат берүү</translation> <translation id="2289270750774289114">Сайт жакын жердеги Bluetooth түзмөктөрүн колдонгону жатканда уруксат суралсын (сунушталат)</translation> +<translation id="2315043854645842844">Кардар тандаган тастыктама операциялык тутумда колдоого алынбайт.</translation> <translation id="2359808026110333948">Улантуу</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> Мб</translation> <translation id="2434158240863470628">Жүктөлүп алынды: <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Көчүрүлдү</translation> <translation id="2822354292072154809"><ph name="CHOSEN_OBJECT_NAME" /> үчүн сайттагы бардык уруксаттар баштапкы абалга келтирилсинби?</translation> <translation id="2870560284913253234">Сайт</translation> +<translation id="2874939134665556319">Мурунку трек</translation> <translation id="2910701580606108292">Сайттар корголгон мазмунду ойнотуудан мурда уруксат суралсын</translation> <translation id="2913331724188855103">Сайттарга куки дайындарын сактоого жана окууга уруксат берүү (сунушталат)</translation> <translation id="2968755619301702150">Тастыктаманы көрүүчү</translation> <translation id="300526633675317032">Ушуну менен <ph name="SIZE_IN_KB" /> сайттардын дайындарынын баары тазаланат.</translation> +<translation id="301521992641321250">Автоматтык түрдө бөгөттөлдү</translation> <translation id="3115898365077584848">Маалыматты көрсөтүү</translation> <translation id="3123473560110926937">Айрым сайттарда бөгөттөлдү</translation> <translation id="3190152372525844641">Chrome үчүн уруксаттарды <ph name="BEGIN_LINK" />Android Жөндөөлөрүнөн<ph name="END_LINK" /> күйгүзүңүз.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Фонду шайкештирүү</translation> <translation id="3822502789641063741">Сайттардын дайындары тазалансынбы?</translation> <translation id="385051799172605136">Артка</translation> +<translation id="3859306556332390985">Алдыга түрдүрүү</translation> <translation id="3955193568934677022">Сайттарга корголгон мазмунду ойнотууга уруксат берүү (сунушталат)</translation> <translation id="3987993985790029246">Шилтм көчр</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">Аталышы</translation> <translation id="4008040567710660924">Белгилүү бир сайттын cookie файлдарына уруксат берүү.</translation> +<translation id="4046123991198612571">Кийинки трек</translation> <translation id="4165986682804962316">Сайт жөндөөлөрү</translation> <translation id="4226663524361240545">Билдирмелер кегенде түзмөк дирилдейт</translation> <translation id="4242533952199664413">Жөндөөлөрдү ачуу</translation> <translation id="4259722352634471385">Чабыттоо бөгөттөлгөн: <ph name="URL" /></translation> <translation id="4278390842282768270">Уруксат берилген</translation> +<translation id="429312253194641664">Сайтта медиа файл ойнотулууда</translation> <translation id="4433925000917964731">Барактын lite-версиясы Google аркылуу алынган.</translation> <translation id="4434045419905280838">Калкыма терезелер жана багыттоолор</translation> <translation id="445467742685312942">Сайттарга корголгон мазмунду ойнотууга уруксат берүү</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Түзмөктөгү бардык уруксаттар жоюлсун</translation> <translation id="4964199952259983386">Chrome'го AR'ди колдоонуусуна уруксат берүү үчүн камераны <ph name="BEGIN_LINK" />Android жөндөөлөрүнөн<ph name="END_LINK" /> күйгүзүңүз.</translation> <translation id="497421865427891073">Алга</translation> +<translation id="4996978546172906250">Төмөнкү аркылуу бөлүшүү</translation> <translation id="5039804452771397117">Уруксат берүү</translation> <translation id="5048398596102334565">Сайттарга сенсорлорду колдонууга уруксат берүү (сунушталат)</translation> <translation id="5063480226653192405">Колдонулушу</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Тазалоо</translation> <translation id="6697925417670533197">Жүктөлүп алынган файлдар</translation> <translation id="6746124502594467657">Төмөн жылдыруу</translation> +<translation id="6766622839693428701">Жабуу үчүн ылдый сүрүңүз.</translation> <translation id="6782111308708962316">Үчүнчү тараптардын вебсайттарына cookie файлдарын окуп, сактаганга тыюу салынат</translation> +<translation id="6790428901817661496">Ойнотуу</translation> <translation id="6818926723028410516">Элементтерди тандоо</translation> <translation id="6864395892908308021">Бул түзмөк NFC'ни окуй албайт</translation> <translation id="6910211073230771657">Жок кылынды</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Сайт камераңызды колдонуп жатат</translation> <translation id="7817023149356982970">Бул сайттан чыгасыз.</translation> <translation id="7828557259026017104">Cookie файлдары сиз баш баккан вебсайттар түзгөн файлдар. Сайттар аларды жеке параметрлериңизди эстеп калуу үчүн колдонушат. Үчүнчү тараптын cookie файлдарын башка сайттар түзөт. Ал сайттарга сиз баш баккан веб-баракчада көрсөтүлгөн жарнамалар жана сүрөттөр сыяктуу айрым мазмун таандык.</translation> +<translation id="7835852323729233924">Медиа ойнотулууда</translation> <translation id="7846076177841592234">Тандоону жокко чыгаруу</translation> <translation id="7846621471902887024">Бардык сайттардан чыгарыласыз.</translation> <translation id="7882806643839505685">Белгилүү бир сайтка добуш чыгарууга уруксат берүү.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Чын эле жергиликтүү дайындарын баарын тазалап, анын ичинде кукилерди, жана бул вебсайттын уруксаттарынын баарын баштапкы абалга келтиргиңиз келеби?</translation> <translation id="8007176423574883786">Бул түзмөк үчүн өчүрүлгөн</translation> <translation id="802154636333426148">Жүктөлүп алынбай калды</translation> +<translation id="8068648041423924542">Тастыктаманы тандоо мүмкүн эмес.</translation> <translation id="8087000398470557479">Бул мазмун <ph name="DOMAIN_NAME" /> доменинен алынып, Google аркылуу жеткирилген.</translation> <translation id="8116925261070264013">Үнсүз кылынган</translation> <translation id="8131740175452115882">Ырастоо</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Сайт камераңызды жана микрофонуңузду колдонуп жатат</translation> <translation id="8380167699614421159">Бул сайт тажатма же адаштыруучу жарнамаларды көрсөтүп жатат</translation> <translation id="8394832520002899662">Сайтка кайтуу үчүн таптаңыз</translation> +<translation id="8425213833346101688">Өзгөртүү</translation> +<translation id="8441146129660941386">Артка түрдүрүү</translation> <translation id="8447861592752582886">Түзмөккө болгон уруксатты жоюу</translation> <translation id="8463851957836045671">Сайт тез жүктөлөт</translation> <translation id="851751545965956758">Сайттардын түзмөктөргө туташуусун бөгөттөө</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Белгилүү бир сайттын cookie файлдарын бөгөттөө.</translation> <translation id="8959122750345127698">Чабыттоо жеткиликсиз: <ph name="URL" /></translation> <translation id="9019902583201351841">Ата-энеңиз башкарат</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Микрофонуңузга мүмкүнчүлүк алуу</translation> <translation id="965817943346481315">Эгер сайт тажатма же адаштыруучу жарнамаларды көрсөтүп баштаса, бөгөттөлсүн (сунушталат)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_lo.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_lo.xtb index 4cefef70cf4..b20ba9b4013 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_lo.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_lo.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">ຕໍ່ໄປ</translation> <translation id="1242008676835033345">ຝັງຕິດໃນ <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">ຢຸດ</translation> +<translation id="1289742167380433257">ເພື່ອຊ່ວຍທ່ານປະຢັດອິນເຕີເນັດ, Google ໄດ້ປັບຮູບຂອງໜ້ານີ້ໃຫ້ເໝາະສົມແລ້ວ.</translation> <translation id="129382876167171263">ໄຟລ໌ທີ່ບັນທຶກໄວ້ໂດຍເວັບໄຊປາກົດຢູ່ບ່ອນນີ້</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> - <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">ເພີ່ມ <ph name="SITE_NAME" /> ເວັບໄຊທ໌ແລ້ວ</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">ຖາມກ່ອນທີ່ຈະອະນຸຍາດໃຫ້ເວັບໄຊສ້າງແຜນທີ່ 3 ມິຕິຂອງສິ່ງທີ່ຢູ່ອ້ອມຂ້າງຕົວທ່ານ ຫຼື ຕາມຕຳແໜ່ງກ້ອງ (ແນະນຳ)</translation> <translation id="2212565012507486665">ອະນຸຍາດຄຸກກີ້</translation> <translation id="2289270750774289114">ຖາມເມື່ອເວັບໄຊຕ້ອງການກວດຫາອຸປະກອນ Bluetooth ທີ່ຢູ່ໃກ້ຄຽງ (ແນະນຳ)</translation> +<translation id="2315043854645842844">ການເລືອກໃບຢັ້ງຢືນເບື້ອງລູກຂ່າຍບໍ່ຖືກຮອງຮັບໂດຍລະບົບປະຕິບັດການ.</translation> <translation id="2359808026110333948">ສືບຕໍ່</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">ການດາວໂຫຼດສຳເລັດແລ້ວ <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">ອັດສຳເນົາແລ້ວ</translation> <translation id="2822354292072154809">ທ່ານແນ່ໃຈບໍ່ວ່າທ່ານຕ້ອງການຣີເຊັດການອະນຸຍາດເວັບໄຊທັງໝົດສຳລັບ <ph name="CHOSEN_OBJECT_NAME" />?</translation> <translation id="2870560284913253234">ເວັບໄຊທ໌</translation> +<translation id="2874939134665556319">ເພງກ່ອນນີ້</translation> <translation id="2910701580606108292">ຖາມກ່ອນທີ່ຈະອະນຸຍາດໃຫ້ເວັບໄຊຫຼິ້ນເນື້ອຫາທີ່ມີການປ້ອງກັນໄວ້</translation> <translation id="2913331724188855103">ອະນຸຍາດໃຫ້ເວັບໄຊທ໌ບັນທຶກ ແລະອ່ານຂໍ້ມູນຄຸກກີ້ (ແນະນຳໃຫ້)</translation> <translation id="2968755619301702150">ຕົວເບິ່ງໃບຢັ້ງຢືນ</translation> <translation id="300526633675317032">ນີ້ຈະລຶບລ້າງທັງໝົດ <ph name="SIZE_IN_KB" /> ຂອງບ່ອນເກັບຂໍ້ມູນເວັບໄຊ.</translation> +<translation id="301521992641321250">ບລັອກອັດຕະໂນມັດແລ້ວ</translation> <translation id="3115898365077584848">ສະແດງຂໍ້ມູນ</translation> <translation id="3123473560110926937">ບລັອກໃນບາງເວັບໄຊ</translation> <translation id="3190152372525844641">ເປີດການອະນຸຍາດສຳລັບ Chrome ຢູ່ໃນ <ph name="BEGIN_LINK" />ການຕັ້ງຄ່າ Android<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">ການຊິ້ງຂໍ້ມູນໃນພື້ນຫຼັງ</translation> <translation id="3822502789641063741">ລຶບລ້າງບ່ອນເກັບຂໍ້ມູນເວັບໄຊບໍ?</translation> <translation id="385051799172605136">ກັບຄືນ</translation> +<translation id="3859306556332390985">ເລື່ອນໄປໜ້າ</translation> <translation id="3955193568934677022">ອະນຸຍາດໃຫ້ເວັບໄຊຕ່າງໆຫຼິ້ນເນື້ອຫາທີ່ໄດ້ຮັບການປົກປ້ອງ (ແນະນຳ)</translation> <translation id="3987993985790029246">ອັດສຳເນົາລິ້ງເຊື່ອມໂຍງ</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">ຫົວຂໍ້</translation> <translation id="4008040567710660924">ອະນຸຍາດຄຸກກີ້ສຳລັບເວັບໄຊສະເພາະ.</translation> +<translation id="4046123991198612571">ເພງຕໍ່ໄປ</translation> <translation id="4165986682804962316">ການຕັ້ງຄ່າເວັບໄຊທ໌</translation> <translation id="4226663524361240545">ການແຈ້ງເຕືອນອາດຈະເຮັດໃຫ້ອຸປະກອນສັ່ນ</translation> <translation id="4242533952199664413">ເປີດການຕັ້ງຄ່າ</translation> <translation id="4259722352634471385">ການນໍາທາງຖືກບລັອກໄວ້: <ph name="URL" /></translation> <translation id="4278390842282768270">ອະນຸຍາດແລ້ວ</translation> +<translation id="429312253194641664">ເວັບໄຊກຳລັງຫຼິ້ນສື່ຢູ່</translation> <translation id="4433925000917964731">ໜ້າ Lite ທີ່ Google ສະໜອງໃຫ້</translation> <translation id="4434045419905280838">ປັອບອັບ ແລະ ການປ່ຽນເສັ້ນທາງ</translation> <translation id="445467742685312942">ອະນຸຍາດໃຫ້ເວັບໄຊຫຼິ້ນເນື້ອຫາທີ່ໄດ້ຮັບການປົກປ້ອງ</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">ຖອນການອະນຸຍາດທັງໝົດສຳລັບອຸປະກອນ</translation> <translation id="4964199952259983386">ເພື່ອອະນຸຍາດໃຫ້ Chrome ໃຊ້ AR, ກະລຸນາເປີດກ້ອງໃນ <ph name="BEGIN_LINK" />ການຕັ້ງຄ່າ Android<ph name="END_LINK" /> ນຳ.</translation> <translation id="497421865427891073">ໄປຂ້າງຫນ້າ</translation> +<translation id="4996978546172906250">ແຊຣ໌ຜ່ານ</translation> <translation id="5039804452771397117">ອະນຸຍາດ</translation> <translation id="5048398596102334565">ອະນຸຍາດໃຫ້ເວັບໄຊເຂົ້າເຖິງເຊັນເຊີກວດຈັບການເຄື່ອນໄຫວ (ແນະນຳ)</translation> <translation id="5063480226653192405">ການນໍາໃຊ້</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">ລຶບ</translation> <translation id="6697925417670533197">ການດາວໂຫຼດທີ່ດຳເນີນຢູ່</translation> <translation id="6746124502594467657">ຍ້າຍລົງ</translation> +<translation id="6766622839693428701">ປັດລົງເພື່ອປິດ.</translation> <translation id="6782111308708962316">ປ້ອງກັນບໍ່ໃຫ້ເວັບໄຊພາກສ່ວນທີສາມບັນທຶກ ແລະ ອ່ານຂໍ້ມູນຄຸກກີ້</translation> +<translation id="6790428901817661496">ຫຼິ້ນ</translation> <translation id="6818926723028410516">ເລືອກລາຍການ</translation> <translation id="6864395892908308021">ອຸປະກອນນີ້ບໍ່ສາມາດອ່ານ NFC ໄດ້</translation> <translation id="6910211073230771657">ລຶບແລ້ວ</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">ເວັບໄຊກຳລັງໃຊ້ກ້ອງຂອງທ່ານຢູ່</translation> <translation id="7817023149356982970">ທ່ານຈະຖືກນຳອອກຈາກລະບົບເວັບໄຊນີ້.</translation> <translation id="7828557259026017104">ຄຸກກີ້ແມ່ນໄຟລ໌ທີ່ສ້າງຂຶ້ນໂດຍເວັບໄຊທີ່ທ່ານເຂົ້າເບິ່ງ. ເວັບໄຊໃຊ້ພວກມັນເພື່ອຈື່ການຕັ້ງຄ່າຂອງທ່ານ. ຄຸກກີ້ພາກສ່ວນທີສາມຖືກສ້າງຂຶ້ນໂດຍເວັບໄຊອື່ນ. ເວັບໄຊເຫຼົ່ານີ້ເປັນເຈົ້າຂອງບາງເນື້ອຫາ ເຊັ່ນ: ໂຄສະນາ ຫຼື ຮູບພາບ ທີ່ທ່ານເຫັນໃນໜ້າເວັບທີ່ທ່ານເຂົ້າເບິ່ງ.</translation> +<translation id="7835852323729233924">ກຳລັງຫຼິ້ນສື່</translation> <translation id="7846076177841592234">ຍົກເລີກການເລືອກ</translation> <translation id="7846621471902887024">ທ່ານຈະຖືກນຳອອກຈາກລະບົບເວັບໄຊທັງໝົດ.</translation> <translation id="7882806643839505685">ອະນຸຍາດສຽງສຳລັບເວັບໄຊສະເພາະໃດໜຶ່ງ.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">ທ່ານແນ່ໃຈບໍວ່າ ທ່ານຕ້ອງການລຶບຂໍ້ມູນໃນເຄື່ອງທັງໝົດ, ລວມທັງຄຸກກີ້, ແລະຕັ້ງຄ່າການອະນຸຍາດທັງໝົດສຳລັບເວັບໄຊທ໌ນີ້?</translation> <translation id="8007176423574883786">ປິດສຳລັບອຸປະກອນນີ້</translation> <translation id="802154636333426148">ການດາວໂຫຼດບໍ່ສຳເລັດ</translation> +<translation id="8068648041423924542">ບໍ່ສາມາດເລືອກໃບຢັ້ງຢືນໄດ້.</translation> <translation id="8087000398470557479">ເນື້ອຫານີ້ມາຈາກ <ph name="DOMAIN_NAME" />, ນຳສົ່ງໂດຍ Google.</translation> <translation id="8116925261070264013">ປິດສຽງແລ້ວ</translation> <translation id="8131740175452115882">ຢືນຢັນ</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">ເວັບໄຊກຳລັງໃຊ້ກ້ອງ ແລະ ໄມໂຄຣໂຟນຂອງທ່ານຢູ່</translation> <translation id="8380167699614421159">ເວັບໄຊນີ້ສະແດງໂຄສະນາທີ່ລົບກວນ ຫຼື ຫຼອກລວງ</translation> <translation id="8394832520002899662">ແຕະເພື່ອກັບຄືນຫາເວັບໄຊ</translation> +<translation id="8425213833346101688">ປ່ຽນແປງ</translation> +<translation id="8441146129660941386">ເລື່ອນກັບຫຼັງ</translation> <translation id="8447861592752582886">ຖອນການອະນຸຍາດອຸປະກອນ</translation> <translation id="8463851957836045671">ເວັບໄຊໄວດີ</translation> <translation id="851751545965956758">ບລັອກບໍ່ໃຫ້ເວັບໄຊເຊື່ອມຕໍ່ກັບອຸປະກອນ</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">ບລັອກຄຸກກີ້ສຳລັບເວັບໄຊສະເພາະ.</translation> <translation id="8959122750345127698">ການນຳທາງແມ່ນບໍ່ສາມາດເຂົ້າເຖິງໄດ້: <ph name="URL" /></translation> <translation id="9019902583201351841">ຈັດການໂດຍຜູ້ປົກຄອງຂອງທ່ານ</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">ເຂົ້າຫາໄມໂຄຣໂຟນຂອງທ່ານ</translation> <translation id="965817943346481315">ບລັອກຖ້າເວັບໄຊສະແດງໂຄສະນາທີ່ລົບກວນ ຫຼື ຫຼອກລວງ (ແນະນຳ)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_lt.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_lt.xtb index 369ae5fb324..f4caf4227a8 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_lt.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_lt.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Kitas</translation> <translation id="1242008676835033345">Įterpta <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Sustabdyti</translation> +<translation id="1289742167380433257">Siekdama apsaugoti jūsų duomenis, „Google“ optimizavo šio puslapio vaizdus.</translation> <translation id="129382876167171263">Svetainių išsaugoti failai rodomi čia</translation> <translation id="1364532808393826295">„<ph name="APP_NAME" />“: <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Pridėta svetainė <ph name="SITE_NAME" /></translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Klausti, ar svetainėms leidžiama kurti jūsų aplinkos 3D žemėlapį ir stebėti kameros padėtį (rekomenduojama)</translation> <translation id="2212565012507486665">Leisti slapukus</translation> <translation id="2289270750774289114">Paklausti, kai svetainė nori atrasti netoliese esančius „Bluetooth“ įrenginius (rekomenduojama)</translation> +<translation id="2315043854645842844">Kliento pasirinkto sertifikato nepalaiko operacinė sistema.</translation> <translation id="2359808026110333948">Tęskite</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">Atsisiųsta: <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Nukopij.</translation> <translation id="2822354292072154809">Ar tikrai norite iš naujo nustatyti visus „<ph name="CHOSEN_OBJECT_NAME" />“ svetainės leidimus?</translation> <translation id="2870560284913253234">Svetainė</translation> +<translation id="2874939134665556319">Ankstesnis takelis</translation> <translation id="2910701580606108292">Paklausti prieš leidžiant svetainėms leisti saugomą turinį</translation> <translation id="2913331724188855103">Leisti svetainėms išsaugoti ir nuskaityti slapukų duomenis (rekomenduojama)</translation> <translation id="2968755619301702150">Sertifikato peržiūros priemonė</translation> <translation id="300526633675317032">Bus išvalyta visa <ph name="SIZE_IN_KB" /> svetainės saugykla.</translation> +<translation id="301521992641321250">Automatiškai užblokuota</translation> <translation id="3115898365077584848">Rodyti informaciją</translation> <translation id="3123473560110926937">Užblokuota kai kuriose svetainėse</translation> <translation id="3190152372525844641">Įjunkite „Chrome“ leidimus <ph name="BEGIN_LINK" />„Android“ nustatymuose<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Fono sinchronizavimas</translation> <translation id="3822502789641063741">Išvalyti svet. saugyklą?</translation> <translation id="385051799172605136">Atgal</translation> +<translation id="3859306556332390985">Eiti pirmyn</translation> <translation id="3955193568934677022">Leisti svetainėms paleisti apsaugotą turinį (rekomenduojama)</translation> <translation id="3987993985790029246">Kop. nuor.</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> iš ?</translation> <translation id="4002066346123236978">Pavadinimas</translation> <translation id="4008040567710660924">Leisti konkrečios svetainės slapukus.</translation> +<translation id="4046123991198612571">Kitas takelis</translation> <translation id="4165986682804962316">Svetainės nustatymai</translation> <translation id="4226663524361240545">Gavus pranešimą įrenginys gali vibruoti</translation> <translation id="4242533952199664413">Atidaryti nustatymus</translation> <translation id="4259722352634471385">Naršymas užblokuotas: <ph name="URL" /></translation> <translation id="4278390842282768270">Leidžiama</translation> +<translation id="429312253194641664">Svetainėje leidžiama medija</translation> <translation id="4433925000917964731">Supaprastintasis puslapis, kurį teikia „Google“</translation> <translation id="4434045419905280838">Iššok. langai ir peradresavimai</translation> <translation id="445467742685312942">Leisti svetainėms leisti saugomą turinį</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Anuliuoti visus įrenginio leidimus</translation> <translation id="4964199952259983386">Norėdami leisti „Chrome“ naudoti AR, taip pat įjunkite fotoaparatą <ph name="BEGIN_LINK" />„Android“ nustatymuose<ph name="END_LINK" />.</translation> <translation id="497421865427891073">Eiti pirmyn</translation> +<translation id="4996978546172906250">Bendrinti per</translation> <translation id="5039804452771397117">Leisti</translation> <translation id="5048398596102334565">Leidžiama svetainėms pasiekti judesio jutiklius (rekomenduojama)</translation> <translation id="5063480226653192405">Naudojimas</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Išvalyti</translation> <translation id="6697925417670533197">Aktyvūs atsisiuntimai</translation> <translation id="6746124502594467657">Perkelti žemyn</translation> +<translation id="6766622839693428701">Perbraukite žemyn, kad uždarytumėte.</translation> <translation id="6782111308708962316">Neleisti trečiosios šalies svetainėms išsaugoti ir skaityti slapukų duomenų</translation> +<translation id="6790428901817661496">Žaisti</translation> <translation id="6818926723028410516">Pasirinkite elementus</translation> <translation id="6864395892908308021">Šis įrenginys negali nuskaityti ALR</translation> <translation id="6910211073230771657">Ištrintas</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Svetainėje naudojamas jūsų fotoaparatas</translation> <translation id="7817023149356982970">Būsite atjungti nuo šios svetainės.</translation> <translation id="7828557259026017104">Slapukai yra svetainių, kuriose lankėtės, sukurti failai. Svetainėse jie naudojami jūsų nuostatoms įsiminti. Trečiųjų šalių slapukus kuria kitos svetainės. Šioms svetainėms priklauso tam tikras tinklalapyje, kuriame lankotės, rodomas turinys, pvz., skelbimai ar vaizdai.</translation> +<translation id="7835852323729233924">Leidžiama medija</translation> <translation id="7846076177841592234">Atšaukti pasirinkimą</translation> <translation id="7846621471902887024">Būsite atjungti nuo visų svetainių.</translation> <translation id="7882806643839505685">Konkrečios svetainės garso leidimas.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Ar tikrai norite išvalyti visus šios svetainės vietinius duomenis, įskaitant slapukus, ir iš naujo nustatyti visus leidimus?</translation> <translation id="8007176423574883786">Išjungta šiame įrenginyje</translation> <translation id="802154636333426148">Įvyko atsisiuntimo klaida</translation> +<translation id="8068648041423924542">Nepavyko pasirinkti sertifikato.</translation> <translation id="8087000398470557479">Šis turinys yra iš domeno <ph name="DOMAIN_NAME" />, kurį teikia „Google“.</translation> <translation id="8116925261070264013">Išjungta</translation> <translation id="8131740175452115882">Patvirtinti</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Svetainėje naudojamas jūsų fotoaparatas ir mikrofonas</translation> <translation id="8380167699614421159">Šioje svetainėje rodomi nepageidaujami arba klaidinantys skelbimai</translation> <translation id="8394832520002899662">Norėdami grįžti į svetainę, palieskite</translation> +<translation id="8425213833346101688">Keisti</translation> +<translation id="8441146129660941386">Ieškoti einant atgal</translation> <translation id="8447861592752582886">Anuliuoti įrenginio leidimą</translation> <translation id="8463851957836045671">Svetainė veikia sparčiai</translation> <translation id="851751545965956758">Blokuoti svetaines, kad nebūtų galima prisijungti prie įrenginių</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Blokuoti konkrečios svetainės slapukus.</translation> <translation id="8959122750345127698">Naršymas nepasiekiamas: <ph name="URL" /></translation> <translation id="9019902583201351841">Tvarko jūsų tėvai</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Prieiga prie mikrofono</translation> <translation id="965817943346481315">Blokuoti, jei svetainėje rodomi nepageidaujami arba klaidinantys skelbimai (rekomenduojama)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_lv.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_lv.xtb index 7808128cb97..e3b52607c46 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_lv.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_lv.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Tālāk</translation> <translation id="1242008676835033345">Iegults vietnē <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Apturēt</translation> +<translation id="1289742167380433257">Lai palīdzētu jums samazināt datu lietojumu, Google optimizēja šajā lapā iekļautos attēlus.</translation> <translation id="129382876167171263">Šeit tiek rādīti tīmekļa vietņu saglabātie faili</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> — <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Tika pievienota vietne <ph name="SITE_NAME" /></translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Vaicāt, pirms ļaut vietnēm izveidot jūsu apkārtnes 3D karti vai izsekot kameras pozīciju (ieteicams)</translation> <translation id="2212565012507486665">Atļaut sīkfailus</translation> <translation id="2289270750774289114">Vaicāt, ja vietne vēlas redzēt tuvumā esošās Bluetooth ierīces (ieteicams)</translation> +<translation id="2315043854645842844">Operētājsistēma neatbalsta klienta puses sertifikāta atlasi.</translation> <translation id="2359808026110333948">Turpināt</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">Lejupielāde pabeigta: <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Nokopēts</translation> <translation id="2822354292072154809">Vai tiešām vēlaties atiestatīt visas vietņu atļaujas, kas piešķirtas šim objektam: <ph name="CHOSEN_OBJECT_NAME" />?</translation> <translation id="2870560284913253234">Vietne</translation> +<translation id="2874939134665556319">Iepriekšējais ieraksts</translation> <translation id="2910701580606108292">Jautāt, pirms atļaut vietnēm atskaņot aizsargātu saturu</translation> <translation id="2913331724188855103">Atļaut vietnēm saglabāt un lasīt sīkfailu datus (ieteicams)</translation> <translation id="2968755619301702150">Sertifikātu skatītājs</translation> <translation id="300526633675317032">Tādējādi tiks notīrīti visi vietnes krātuves dati (<ph name="SIZE_IN_KB" />).</translation> +<translation id="301521992641321250">Automātiski bloķēta</translation> <translation id="3115898365077584848">Rādīt informāciju</translation> <translation id="3123473560110926937">Bloķētas dažās vietnēs</translation> <translation id="3190152372525844641"><ph name="BEGIN_LINK" />Android iestatījumos<ph name="END_LINK" /> ieslēdziet atļaujas pārlūkam Chrome.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Sinhronizācija fonā</translation> <translation id="3822502789641063741">Vai notīrīt vietnes krātuvi?</translation> <translation id="385051799172605136">Atpakaļ</translation> +<translation id="3859306556332390985">Pārtīt uz priekšu</translation> <translation id="3955193568934677022">Atļaut vietnēm atskaņot aizsargātu saturu (ieteicams)</translation> <translation id="3987993985790029246">Saites kopēšana</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> no ?</translation> <translation id="4002066346123236978">Nosaukums</translation> <translation id="4008040567710660924">Atļaut sīkfailus konkrētai vietnei.</translation> +<translation id="4046123991198612571">Nākamais ieraksts</translation> <translation id="4165986682804962316">Vietnes iestatījumi</translation> <translation id="4226663524361240545">Saņemot paziņojumu, ierīce var vibrēt.</translation> <translation id="4242533952199664413">Atvērt iestatījumus</translation> <translation id="4259722352634471385">Navigācija ir bloķēta: <ph name="URL" /></translation> <translation id="4278390842282768270">Atļauts</translation> +<translation id="429312253194641664">Vietne atskaņo multivides saturu</translation> <translation id="4433925000917964731">Vienkāršota lapa, ko nodrošina Google</translation> <translation id="4434045419905280838">Uznirstošie elem. un novirzīšana</translation> <translation id="445467742685312942">Ļaut vietnēm atskaņot aizsargātu saturu</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Atsaukt visas atļaujas, kas piešķirtas ierīcei</translation> <translation id="4964199952259983386">Lai pārlūkā Chrome varētu izmantot papildināto realitāti, ieslēdziet arī kameras atļauju <ph name="BEGIN_LINK" />Android iestatījumos<ph name="END_LINK" />.</translation> <translation id="497421865427891073">Doties uz priekšu</translation> +<translation id="4996978546172906250">Kopīgošanas veids:</translation> <translation id="5039804452771397117">Atļaut</translation> <translation id="5048398596102334565">Atļaut vietnēm piekļūt kustību sensoriem (ieteicams)</translation> <translation id="5063480226653192405">Lietojums</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Notīrīt</translation> <translation id="6697925417670533197">Aktīvas lejupielādes</translation> <translation id="6746124502594467657">Pārvietot uz leju</translation> +<translation id="6766622839693428701">Velciet uz leju, lai aizvērtu.</translation> <translation id="6782111308708962316">Neļaut trešo pušu vietnēm saglabāt un nolasīt sīkfailu datus</translation> +<translation id="6790428901817661496">Atskaņot</translation> <translation id="6818926723028410516">Vienumu atlase</translation> <translation id="6864395892908308021">Šī ierīce nevar lasīt NFC</translation> <translation id="6910211073230771657">Dzēsts</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Kāda vietne izmanto jūsu kameru</translation> <translation id="7817023149356982970">Jūs tiksiet izrakstīts no šīs vietnes.</translation> <translation id="7828557259026017104">Sīkfaili ir faili, ko izveido jūsu apmeklētās vietnes. Vietnes izmanto šos sīkfailus, lai atcerētos jūsu preferences. Trešo pušu sīkfailus izveido citas vietnes. Jūsu apmeklētajā tīmekļa lapā var būt ietverts citu vietņu saturs, piemēram, reklāmas vai attēli.</translation> +<translation id="7835852323729233924">Multivides atskaņošana</translation> <translation id="7846076177841592234">Atcelt atlasi</translation> <translation id="7846621471902887024">Jūs tiksiet izrakstīts no visām vietnēm.</translation> <translation id="7882806643839505685">Atļaut skaņu konkrētai vietnei</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Vai tiešām vēlaties notīrīt visus ar šo vietni saistītos lokālos datus, tostarp sīkfailus, un atiestatīt visas atļaujas?</translation> <translation id="8007176423574883786">Izslēgts šai ierīcei</translation> <translation id="802154636333426148">Lejupielāde neizdevās</translation> +<translation id="8068648041423924542">Nevar atlasīt sertifikātu.</translation> <translation id="8087000398470557479">Šis saturs ir no vietnes <ph name="DOMAIN_NAME" />, ko nodrošina Google.</translation> <translation id="8116925261070264013">Izslēgta skaņa</translation> <translation id="8131740175452115882">Apstiprināt</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Kāda vietne izmanto jūsu kameru un mikrofonu</translation> <translation id="8380167699614421159">Šajā vietnē tiek rādītas traucējošas vai maldinošas reklāmas</translation> <translation id="8394832520002899662">Lai atgrieztos vietnē, pieskarieties šeit</translation> +<translation id="8425213833346101688">Mainīt</translation> +<translation id="8441146129660941386">Pārtīt atpakaļ</translation> <translation id="8447861592752582886">Atsaukt ierīces atļauju</translation> <translation id="8463851957836045671">Ātra vietnes darbība</translation> <translation id="851751545965956758">Neļaut vietnēm izveidot savienojumu ar ierīci</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Bloķēt sīkfailus konkrētai vietnei.</translation> <translation id="8959122750345127698">Navigācija nav sasniedzama: <ph name="URL" /></translation> <translation id="9019902583201351841">Pārvalda jūsu vecāki</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Piekļuve mikrofonam</translation> <translation id="965817943346481315">Bloķēt, ja vietnē tiek rādītas traucējošas vai maldinošas reklāmas (ieteicams)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_mk.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_mk.xtb index 17bf88a0b67..8ba453167da 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_mk.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_mk.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Следно</translation> <translation id="1242008676835033345">Вметнато во <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Запри</translation> +<translation id="1289742167380433257">Google ги оптимизираше сликите на страницава за да ви заштеди интернет.</translation> <translation id="129382876167171263">Датотеките зачувани од веб-сајтовите се појавуваат тука</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> - <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Локацијата <ph name="SITE_NAME" /> е додадена</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Прашувај пред да им дозволиш на сајтовите да создадат 3D-карта на опкружувањето или да ја следат позицијата на камерата (препорачано)</translation> <translation id="2212565012507486665">Дозволи колачиња</translation> <translation id="2289270750774289114">Прашај кога некој сајт сака да открива уреди со Bluetooth во близина (се препорачува)</translation> +<translation id="2315043854645842844">Оперативниот систем не поддржува избор на сертификат од страна на клиентот.</translation> <translation id="2359808026110333948">Продолжи</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">Преземањето е завршено <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Копирано</translation> <translation id="2822354292072154809">Сигурно ли сакате да ги ресетирате сите дозволи на сајтот за <ph name="CHOSEN_OBJECT_NAME" />?</translation> <translation id="2870560284913253234">Локација</translation> +<translation id="2874939134665556319">Претходна песна</translation> <translation id="2910701580606108292">Прашај пред да дозволиш сајтовите да пуштаат заштитени содржини</translation> <translation id="2913331724188855103">Дозволете локациите да зачувуваат и читаат податоци за колачињата (препорачано)</translation> <translation id="2968755619301702150">Прикажувач на сертификат</translation> <translation id="300526633675317032">Ова ќе ги избрише сите <ph name="SIZE_IN_KB" /> од просторот на веб-сајтот.</translation> +<translation id="301521992641321250">Автоматски блокирана</translation> <translation id="3115898365077584848">Прикажи ги информациите</translation> <translation id="3123473560110926937">Блокирано на некои сајтови</translation> <translation id="3190152372525844641">Вклучете ги дозволите за Chrome во <ph name="BEGIN_LINK" />Поставки на Android<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Синхронизација во заднина</translation> <translation id="3822502789641063741">Испразни го просторот?</translation> <translation id="385051799172605136">Назад</translation> +<translation id="3859306556332390985">Барај понапред</translation> <translation id="3955193568934677022">Дозволете сајтовите да пуштаат заштитени содржини (се препорачува)</translation> <translation id="3987993985790029246">Копирај линк</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> <translation id="4002066346123236978">Наслов</translation> <translation id="4008040567710660924">Дозволете колачиња за конкретен сајт.</translation> +<translation id="4046123991198612571">Следна песна</translation> <translation id="4165986682804962316">Поставки на локација</translation> <translation id="4226663524361240545">Известувањата може да предизвикаат вибрации на уредот</translation> <translation id="4242533952199664413">Отвори ги поставките</translation> <translation id="4259722352634471385">Навигацијата е блокирана: <ph name="URL" /></translation> <translation id="4278390842282768270">Дозволено</translation> +<translation id="429312253194641664">Сајтот репродуцира аудиовизуелни содржини</translation> <translation id="4433925000917964731">Lite-страница овозможена од Google</translation> <translation id="4434045419905280838">Скокачки прозорци/пренасочувања</translation> <translation id="445467742685312942">Дозволи сајтовите да пуштаат заштитени содржини</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Повлечи ги сите дозволи за уредот</translation> <translation id="4964199952259983386">За да дозволите Chrome да користи AR, вклучете ја и камерата во <ph name="BEGIN_LINK" />Поставките за Android<ph name="END_LINK" />.</translation> <translation id="497421865427891073">Оди напред</translation> +<translation id="4996978546172906250">Сподели преку</translation> <translation id="5039804452771397117">Дозволи</translation> <translation id="5048398596102334565">Дозволете сајтовите да пристапуваат до сензорите за движење (препорачано)</translation> <translation id="5063480226653192405">Користење</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Исчисти</translation> <translation id="6697925417670533197">Активни преземања</translation> <translation id="6746124502594467657">Премести долу</translation> +<translation id="6766622839693428701">Повлечете надолу за да затворите.</translation> <translation id="6782111308708962316">Спречи ги веб-сајтовите на трети лица да зачувуваат и читаат податоци за колачињата</translation> +<translation id="6790428901817661496">Репродуцирај</translation> <translation id="6818926723028410516">Изберете ставки</translation> <translation id="6864395892908308021">Уредов не може да чита NFC</translation> <translation id="6910211073230771657">Избришано</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Сајтот ја користи камерата</translation> <translation id="7817023149356982970">Ќе ве одјавиме од сајтов.</translation> <translation id="7828557259026017104">Колачињата се датотеки создадени од веб-сајтовите што ги посетувате. Сајтовите ги користат за да ги запомнат вашите поставки. Колачињата од трети страни се создадени од други сајтови. Овие сајтови се сопственици на дел од содржините, како рекламите или сликите што ги гледате на веб-страницата што ја посетувате.</translation> +<translation id="7835852323729233924">Пуштање аудиовизуелни содржини</translation> <translation id="7846076177841592234">Откажи избор</translation> <translation id="7846621471902887024">Ќе ве одјавиме од сите сајтови.</translation> <translation id="7882806643839505685">Дозволете го звукот за одреден сајт.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Дали сте сигурни дека сакате да ги исчистите сите локални податоци, вклучувајќи ги колачињата, и да ги ресетирате сите дозволи за веб-локацијата?</translation> <translation id="8007176423574883786">Исклучена за овој уред</translation> <translation id="802154636333426148">Неуспешно преземање</translation> +<translation id="8068648041423924542">Сертификатот не може да се избере.</translation> <translation id="8087000398470557479">Оваа содржина е од <ph name="DOMAIN_NAME" />, овозможена од Google.</translation> <translation id="8116925261070264013">Со исклучен звук</translation> <translation id="8131740175452115882">Потврди</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Сајтот ги користи камерата и микрофонот</translation> <translation id="8380167699614421159">Сајтов прикажува нападни или лажни реклами</translation> <translation id="8394832520002899662">Допрете за да се вратите на сајтот</translation> +<translation id="8425213833346101688">Промени</translation> +<translation id="8441146129660941386">Барај поназад</translation> <translation id="8447861592752582886">Отповикај ја дозволата за пристап до уредот</translation> <translation id="8463851957836045671">Сајтот е брз</translation> <translation id="851751545965956758">Блокирај ги сајтовите од поврзување со уреди</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Блокирајте колачиња за одреден сајт.</translation> <translation id="8959122750345127698">Навигацијата е недостапна: <ph name="URL" /></translation> <translation id="9019902583201351841">Управувано од вашите родители</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Пристапи до микрофонот</translation> <translation id="965817943346481315">Блокирај ако сајтот прикажува нападни или лажни реклами (препорачано)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ml.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ml.xtb index 43f847cd546..9caf00796e0 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ml.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ml.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">അടുത്തത്</translation> <translation id="1242008676835033345"><ph name="WEBSITE_URL" />-ൽ ഉൾച്ചേർത്തത്</translation> <translation id="1272079795634619415">നിര്ത്തുക</translation> +<translation id="1289742167380433257">നിങ്ങളുടെ ഡാറ്റ സംരക്ഷിക്കുന്നതിന്, ഈ പേജിലെ ചിത്രങ്ങൾ Google ഒപ്റ്റിമൈസ് ചെയ്തിരിക്കുന്നു.</translation> <translation id="129382876167171263">വെബ്സൈറ്റുകൾ സംരക്ഷിച്ചിട്ടുള്ള ഫയലുകള് ഇവിടെ ദൃശ്യമാവും</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> - <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676"><ph name="SITE_NAME" /> എന്ന സൈറ്റ് ചേർത്തൂ</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">നിങ്ങളുടെ ചുറ്റുപാടുകളുടെ 3D മാപ്പ് സൃഷ്ടിക്കുന്നതിനോ ക്യാമറയുടെ സ്ഥാനം ട്രാക്ക് ചെയ്യുന്നതിനോ സൈറ്റുകളെ അനുവദിക്കുന്നതിന് മുമ്പ് ചോദിക്കുക (ശുപാർശ ചെയ്യുന്നത്)</translation> <translation id="2212565012507486665">കുക്കികൾ അനുവദിക്കുക</translation> <translation id="2289270750774289114">സമീപത്തുള്ള Bluetooth ഉപകരണങ്ങൾ കണ്ടെത്താൻ ഒരു സൈറ്റ് താൽപ്പര്യപ്പെടുമ്പോൾ ചോദിക്കുക (ശുപാർശചെയ്തത്)</translation> +<translation id="2315043854645842844">ഓപ്പറേറ്റിംഗ് സിസ്റ്റം ക്ലയന്റിന്റെ സർട്ടിഫിക്കറ്റ് തിരഞ്ഞെടുക്കലിനെ പിന്തുണയ്ക്കുന്നില്ല.</translation> <translation id="2359808026110333948">തുടരുക</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">ഡൗൺലോഡ് പൂർത്തിയായി <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">പകർത്തി</translation> <translation id="2822354292072154809"><ph name="CHOSEN_OBJECT_NAME" /> എന്നതിനുള്ള എല്ലാ സൈറ്റ് അനുമതികളും പുനഃസജ്ജീകരിക്കണമെന്ന് നിങ്ങൾക്ക് ഉറപ്പാണോ?</translation> <translation id="2870560284913253234">സൈറ്റ്</translation> +<translation id="2874939134665556319">മുമ്പത്തെ ട്രാക്ക്</translation> <translation id="2910701580606108292">പരിരക്ഷിത ഉള്ളടക്കം പ്ലേ ചെയ്യാൻ സൈറ്റുകളെ അനുവദിക്കുന്നതിന് മുമ്പ് ചോദിക്കുക</translation> <translation id="2913331724188855103">കുക്കി ഡാറ്റ സംരക്ഷിക്കുന്നതിനും വായിക്കുന്നതിനും സൈറ്റുകളെ അനുവദിക്കുക (ശുപാർശചെയ്തത്)</translation> <translation id="2968755619301702150">സർട്ടിഫിക്കറ്റ് വ്യൂവർ</translation> <translation id="300526633675317032">ഇത് വെബ്സൈറ്റ് സ്റ്റോറേജിലെ <ph name="SIZE_IN_KB" /> പൂർണ്ണമായും മായ്ക്കും.</translation> +<translation id="301521992641321250">സ്വയമേവ ബ്ലോക്കുചെയ്തു</translation> <translation id="3115898365077584848">വിവരങ്ങൾ കാണിക്കുക</translation> <translation id="3123473560110926937">ചില സൈറ്റുകളിൽ ബ്ലോക്ക് ചെയ്തിരിക്കുന്നു</translation> <translation id="3190152372525844641"><ph name="BEGIN_LINK" />Android ക്രമീകരണത്തിൽ<ph name="END_LINK" /> Chrome-നായി അനുമതികൾ ഓണാക്കുക.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">പശ്ചാത്തല സമന്വയിപ്പിക്കൽ</translation> <translation id="3822502789641063741">സൈറ്റ് സ്റ്റോറേജ് മായ്ക്കണോ?</translation> <translation id="385051799172605136">പിന്നോട്ട്</translation> +<translation id="3859306556332390985">മുന്നോട്ട് നീക്കുക</translation> <translation id="3955193568934677022">പരിരക്ഷിത ഉള്ളടക്കം പ്ലേ ചെയ്യാൻ സൈറ്റുകളെ അനുവദിക്കുക (ശുപാർശ ചെയ്തിരിക്കുന്നു)</translation> <translation id="3987993985790029246">ലിങ്ക് പകർത്തുക</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">ശീർഷകം</translation> <translation id="4008040567710660924">ഒരു പ്രത്യേക സൈറ്റിനായി കുക്കികൾ അനുവദിക്കുക.</translation> +<translation id="4046123991198612571">അടുത്ത ട്രാക്ക്</translation> <translation id="4165986682804962316">സൈറ്റ് ക്രമീകരണങ്ങൾ</translation> <translation id="4226663524361240545">അറിയിപ്പുകൾ ലഭിക്കുമ്പോൾ ഉപകരണം വൈബ്രേറ്റ് ചെയ്തേക്കാം</translation> <translation id="4242533952199664413">ക്രമീകരണം തുറക്കുക</translation> <translation id="4259722352634471385">നാവിഗേഷൻ തടഞ്ഞിരിക്കുന്നു: <ph name="URL" /></translation> <translation id="4278390842282768270">അനുവദനീയം</translation> +<translation id="429312253194641664">സൈറ്റ്, മീഡിയ പ്ലേ ചെയ്യുന്നു</translation> <translation id="4433925000917964731">Google നല്കുന്ന ലൈറ്റ് പേജ്</translation> <translation id="4434045419905280838">പോപ്-അപ്പുകളും റീഡയറക്റ്റുകളും</translation> <translation id="445467742685312942">പരിരക്ഷിത ഉള്ളടക്കം പ്ലേ ചെയ്യാൻ സൈറ്റുകളെ അനുവദിക്കുക</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">ഉപകരണത്തിനുള്ള എല്ലാ അനുമതികളും അസാധുവാക്കുക</translation> <translation id="4964199952259983386">Chrome-നെ AR ഉപയോഗിക്കാൻ അനുവദിക്കുന്നതിന് <ph name="BEGIN_LINK" />Android ക്രമീകരണത്തിൽ<ph name="END_LINK" /> ക്യാമറയും ഓണാക്കുക.</translation> <translation id="497421865427891073">മുന്നോട്ട് പോകുക</translation> +<translation id="4996978546172906250">ഇതുവഴി പങ്കിടുക</translation> <translation id="5039804452771397117">അനുവദിക്കൂ</translation> <translation id="5048398596102334565">നിങ്ങളുടെ ചലന സെൻസറുകൾ ആക്സസ് ചെയ്യാൻ സൈറ്റുകളെ അനുവദിക്കുക (ശുപാർശ ചെയ്യുന്നത്)</translation> <translation id="5063480226653192405">ഉപയോഗം</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">മായ്ക്കുക</translation> <translation id="6697925417670533197">സജീവ ഡൗൺലോഡുകൾ</translation> <translation id="6746124502594467657">താഴേക്ക് നീക്കുക</translation> +<translation id="6766622839693428701">അവസാനിപ്പിക്കാൻ താഴേക്ക് സ്വൈപ്പ് ചെയ്യുക.</translation> <translation id="6782111308708962316">കുക്കി വിവരം സംരക്ഷിക്കുകയും വായിക്കുകയും ചെയ്യുന്നതിൽ നിന്ന് മൂന്നാംകക്ഷി വെബ്സൈറ്റുകളെ തടയുക</translation> +<translation id="6790428901817661496">പ്ലേചെയ്യുക</translation> <translation id="6818926723028410516">ഇനങ്ങൾ തിരഞ്ഞെടുക്കുക</translation> <translation id="6864395892908308021">ഈ ഉപകരണത്തിന് NFC റീഡ് ചെയ്യാനാവില്ല</translation> <translation id="6910211073230771657">ഇല്ലാതാക്കി</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">ഒരു സൈറ്റ് നിങ്ങളുടെ ക്യാമറ ഉപയോഗിക്കുന്നു</translation> <translation id="7817023149356982970">നിങ്ങൾ ഈ സൈറ്റിൽ നിന്ന് സൈൻ ഔട്ടാകും.</translation> <translation id="7828557259026017104">നിങ്ങൾ സന്ദർശിക്കുന്ന വെബ്സൈറ്റുകൾ സൃഷ്ടിക്കുന്ന ഫയലുകളാണ് കുക്കികൾ. നിങ്ങളുടെ മുൻഗണനകൾ ഓർമ്മിക്കാൻ സൈറ്റുകൾ അവ ഉപയോഗിക്കുന്നു. മൂന്നാം കക്ഷി കുക്കികളെ സൃഷ്ടിക്കുന്നത് മറ്റ് സൈറ്റുകളാണ്. നിങ്ങൾ സന്ദർശിക്കുന്ന വെബ്പേജിൽ കാണുന്ന പരസ്യങ്ങളോ ചിത്രങ്ങളോ പോലുള്ള ചില ഉള്ളടക്കം ഈ സൈറ്റുകളുടെ ഉടമസ്ഥതയിലാണ്.</translation> +<translation id="7835852323729233924">മീഡിയ പ്ലേ ചെയ്യുന്നു</translation> <translation id="7846076177841592234">തിരഞ്ഞെടുത്തത് റദ്ദാക്കുക</translation> <translation id="7846621471902887024">എല്ലാ സൈറ്റുകളിൽ നിന്നും നിങ്ങൾ സൈൻ ഔട്ട് ചെയ്യപ്പെടും.</translation> <translation id="7882806643839505685">ഒരു പ്രത്യേക സൈറ്റിനായി ശബ്ദം അനുവദിക്കുക.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">കുക്കികൾ ഉൾപ്പെടെ എല്ലാ പ്രാദേശിക വിവരവും മായ്ച്ച് ഈ വെബ്സൈറ്റിനായുള്ള എല്ലാ അനുമതികളും റീസെറ്റ് ചെയ്യാൻ താൽപ്പര്യമുണ്ടോ?</translation> <translation id="8007176423574883786">ഈ ഉപകരണത്തിനായി ഓഫാക്കി</translation> <translation id="802154636333426148">ഡൗൺലോഡ് പരാജയപ്പെട്ടു</translation> +<translation id="8068648041423924542">സർട്ടിഫിക്കറ്റ് തിരഞ്ഞെടുക്കാനാവുന്നില്ല.</translation> <translation id="8087000398470557479">ഈ ഉള്ളടക്കം Google-ൽ നിന്നുള്ള <ph name="DOMAIN_NAME" /> ഡൊമെയ്നിൽ നിന്നുള്ളതാണ്.</translation> <translation id="8116925261070264013">മ്യൂട്ടുചെയ്തു</translation> <translation id="8131740175452115882">സ്ഥിരീകരിക്കുക</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">ഒരു സൈറ്റ് നിങ്ങളുടെ ക്യാമറയും മൈക്രോഫോണും ഉപയോഗിക്കുന്നു</translation> <translation id="8380167699614421159">ഈ സൈറ്റ്, അനാവശ്യമോ തെറ്റിദ്ധരിപ്പിക്കുന്നതോ ആയ പരസ്യങ്ങള് കാണിക്കുന്നു</translation> <translation id="8394832520002899662">സൈറ്റിലേക്ക് മടങ്ങാൻ ടാപ്പ് ചെയ്യുക</translation> +<translation id="8425213833346101688">മാറ്റുക</translation> +<translation id="8441146129660941386">പുറകിലേക്ക് സീക്കുചെയ്യുക</translation> <translation id="8447861592752582886">ഉപകരണ അനുമതി റദ്ദാക്കുക</translation> <translation id="8463851957836045671">വളരെ വേഗതയുള്ള സൈറ്റ്</translation> <translation id="851751545965956758">ഉപകരണങ്ങളിലേക്ക് കണക്റ്റ് ചെയ്യുന്നതിൽ നിന്ന് സൈറ്റുകളെ ബ്ലോക്ക് ചെയ്യുക</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">ഒരു പ്രത്യേക സൈറ്റിനായി കുക്കികൾ ബ്ലോക്ക് ചെയ്യുക.</translation> <translation id="8959122750345127698">നാവിഗേഷൻ ലഭ്യമല്ല: <ph name="URL" /></translation> <translation id="9019902583201351841">നിങ്ങളുടെ രക്ഷിതാക്കൾ നിയന്ത്രിക്കുന്നു</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">നിങ്ങളുടെ മൈക്രോഫോൺ ആക്സസ് ചെയ്യുക</translation> <translation id="965817943346481315">സൈറ്റ്, അനാവശ്യമോ തെറ്റിദ്ധരിപ്പിക്കുന്നതോ ആയ പരസ്യങ്ങള് കാണിക്കുന്നുണ്ടെങ്കില് ബ്ലോക്ക് ചെയ്യുക (ശുപാര്ശ ചെയ്യുന്നു)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_mn.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_mn.xtb index be39f27ded0..513b6707fa6 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_mn.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_mn.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Дараагийнх</translation> <translation id="1242008676835033345"><ph name="WEBSITE_URL" />-д оруулсан</translation> <translation id="1272079795634619415">Зогс</translation> +<translation id="1289742167380433257">Таны өгөгдлийг хадгалахын тулд Google энэ хуудасны зургуудыг оновчилсон байна.</translation> <translation id="129382876167171263">Вэб сайтын хадгалсан файлыг энд харуулна</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> - <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Сайт <ph name="SITE_NAME" /> нэмсэн</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Сайтуудад таны эргэн тойрны 3D газрын зургийг үүсгэх эсвэл камерын хөдөлгөөнийг хянахыг зөвшөөрөхийн өмнө асуух (санал болгосон)</translation> <translation id="2212565012507486665">Күүкиг зөвшөөрөх</translation> <translation id="2289270750774289114">Сайт ойролцоох Bluetooth төхөөрөмжийг илрүүлэх хүсэлтэй үед асуух (санал болгосон)</translation> +<translation id="2315043854645842844">Үйлчлүүлэгч талын сертификатын сонголтыг үйлдлийн системээс дэмжээгүй.</translation> <translation id="2359808026110333948">Цааш</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> мегабайт</translation> <translation id="2434158240863470628">Татаж дууссан <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Хуулсан</translation> <translation id="2822354292072154809">Та <ph name="CHOSEN_OBJECT_NAME" />-н бүх сайтын зөвшөөрлийг шинэчлэх үү?</translation> <translation id="2870560284913253234">Ажлын талбар</translation> +<translation id="2874939134665556319">Өмнөх бичлэг</translation> <translation id="2910701580606108292">Сайтад хамгаалалттай контент тоглуулахыг зөвшөөрөхөөс өмнө асуух</translation> <translation id="2913331724188855103">Cookie data-г хадгалах мөн унших боломжийг сайтуудад олгох (зөвлөж байна)</translation> <translation id="2968755619301702150">Сертификат харагч</translation> <translation id="300526633675317032">Энэ нь вэб хуудасны сангийн бүх <ph name="SIZE_IN_KB" />-г устгах болно.</translation> +<translation id="301521992641321250">Автоматаар блок хийсэн</translation> <translation id="3115898365077584848">Мэдээллийг харуулах</translation> <translation id="3123473560110926937">Зарим сайт дээр блоклосон</translation> <translation id="3190152372525844641">Chrome-ын зөвшөөрлийг <ph name="BEGIN_LINK" />Android-ын Тохиргоо<ph name="END_LINK" />-д асаагаарай.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Дэвсгэрт синк хийх</translation> <translation id="3822502789641063741">Сайтын санг устгах уу?</translation> <translation id="385051799172605136">Буцах</translation> +<translation id="3859306556332390985">Урагш хайх</translation> <translation id="3955193568934677022">Сайтад хамгаалсан агуулгыг тоглохыг зөвшөөрөх (санал болгосон)</translation> <translation id="3987993985790029246">Холбоосыг хуулах</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">Гарчиг</translation> <translation id="4008040567710660924">Күүкиг тодорхой сайтад зөвшөөрнө үү.</translation> +<translation id="4046123991198612571">Дараагийн бичлэг</translation> <translation id="4165986682804962316">Сайтын тохиргоо</translation> <translation id="4226663524361240545">Мэдэгдэл ирэхэд төхөөрөмж чичрэнэ</translation> <translation id="4242533952199664413">Нээлттэй тохиргоо</translation> <translation id="4259722352634471385">Навигацыг хориглосон байна: <ph name="URL" /></translation> <translation id="4278390842282768270">Зөвшөөрөгдсөн</translation> +<translation id="429312253194641664">Сайт медиа тоглуулж байна</translation> <translation id="4433925000917964731">Google-с өгч буй энгийн хуудас</translation> <translation id="4434045419905280838">Попап болон дахин чиглүүлэлт</translation> <translation id="445467742685312942">Сайтуудад хамгаалагдсан контент тоглуулахыг зөвшөөрөх</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Төхөөрөмжийн бүх зөвшөөрлийг цуцлах</translation> <translation id="4964199952259983386">AR ашиглах боломжийг Chrome-д олгохын тулд камерыг <ph name="BEGIN_LINK" />Android тохиргоо<ph name="END_LINK" /> хэсэгт мөн асаана уу.</translation> <translation id="497421865427891073">Цаашаа явах</translation> +<translation id="4996978546172906250">-аар хуваалцах</translation> <translation id="5039804452771397117">Зөвшөөрөх</translation> <translation id="5048398596102334565">Сайтад хөдөлгөөн мэдрэгчид хандахыг зөвшөөрөх (санал болгосон)</translation> <translation id="5063480226653192405">Ашиглалт</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Цэвэрлэх</translation> <translation id="6697925417670533197">Идэвхтэй татаж авсан файл</translation> <translation id="6746124502594467657">Доош зөөх</translation> +<translation id="6766622839693428701">Хаахын тулд доош шударна уу.</translation> <translation id="6782111308708962316">Күүки өгөгдлийг гуравдагч талын вэб хуудсанд хадгалж, уншихаас сэргийлэх</translation> +<translation id="6790428901817661496">Тоглуулах</translation> <translation id="6818926723028410516">Зүйл сонгох</translation> <translation id="6864395892908308021">Энэ төхөөрөмж NFC-г унших боломжгүй байна</translation> <translation id="6910211073230771657">Устгасан</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Сайт таны камерыг ашиглаж байна</translation> <translation id="7817023149356982970">Та энэ сайтаас гарна.</translation> <translation id="7828557259026017104">Күүки нь таны зочилдог вэб сайтуудын үүсгэдэг файл юм. Сайтууд нь таны сонголтыг санахын тулд түүнийг ашигладаг. Гуравдагч талын күүкиг бусад сайт үүсгэдэг. Эдгээр сайт нь таны зочилдог вэб хуудсан дээрээ хардаг зар эсвэл зураг зэрэг контентын заримыг нь эзэмшдэг.</translation> +<translation id="7835852323729233924">Медиаг тоглуулж байна</translation> <translation id="7846076177841592234">Сонголтыг цуцлах</translation> <translation id="7846621471902887024">Та бүх сайтаас гарах болно.</translation> <translation id="7882806643839505685">Тодорхой сайтад дуу тоглуулахыг зөвшөөрнө үү.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Та cookies гэх мэт энэ вэбсайтны бүх мэдээллийг устгах мөн бүх зөвшөөрлийг дахин тохируулахдаа итгэлтэй байна уу?</translation> <translation id="8007176423574883786">Энэ төхөөрөмж дээр унтраастай байна</translation> <translation id="802154636333426148">Татаж чадсангүй</translation> +<translation id="8068648041423924542">Сертификат сонгох боломжгүй.</translation> <translation id="8087000398470557479"><ph name="DOMAIN_NAME" />-н энэ агуулгыг Google танд хүргэж байна.</translation> <translation id="8116925261070264013">Дууг хаасан</translation> <translation id="8131740175452115882">Батлах</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Сайт таны камер болон микрофоныг ашиглаж байна</translation> <translation id="8380167699614421159">Энэ сайт төвөгтэй эсвэл хуурамч зар харуулдаг</translation> <translation id="8394832520002899662">Сайт руу буцахын тулд товшино уу</translation> +<translation id="8425213833346101688">Өөрчлөлт</translation> +<translation id="8441146129660941386">Буцаж хайх</translation> <translation id="8447861592752582886">Төхөөрөмжийн зөвшөөрлийг хүчингүй болгох</translation> <translation id="8463851957836045671">Сайт хурдан</translation> <translation id="851751545965956758">Сайтуудыг төхөөрөмжүүдэд холбогдохыг нь блоклох</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Күүкиг тодорхой сайтад хориглоно уу.</translation> <translation id="8959122750345127698">Навигацтай холбогдох боломжгүй байна: <ph name="URL" /></translation> <translation id="9019902583201351841">Эцэг, эх нь хариуцан удирдаж байна</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Микрофонд хандах</translation> <translation id="965817943346481315">Сайт төвөгтэй эсвэл хуурамч зар харуулсан тохиолдолд блоклох (санал болгосон)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_mr.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_mr.xtb index ce9bf9403a6..fabc78405eb 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_mr.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_mr.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">पुढील</translation> <translation id="1242008676835033345"><ph name="WEBSITE_URL" /> वर एम्बेड केले</translation> <translation id="1272079795634619415">थांबा</translation> +<translation id="1289742167380433257">तुमचा डेटा वाचवण्यासाठी, या पेजच्या इमेज Google ने ऑप्टिमाइझ केल्या आहेत.</translation> <translation id="129382876167171263">वेबसाइटद्वारे सेव्ह केलेल्या फाइल येथे दिसतील</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> - <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676"><ph name="SITE_NAME" /> साइट जोडली</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">साइटना तुमच्या आसपासच्या परिसराचा 3D नकाशा तयार करू किंवा कॅमेर्याचे स्थान ट्रॅक करू देण्याआधी विचारा (शिफारस केलेले)</translation> <translation id="2212565012507486665">कुकींना अनुमती द्या</translation> <translation id="2289270750774289114">साइटला केव्हा जवळपासचे ब्लूटूथ डिव्हाइस शोधायचे आहे हे विचारा (शिफारस केलेले)</translation> +<translation id="2315043854645842844">क्लायंट साइड प्रमाणपत्र निवडीला ऑपरेटिंग सिस्टमचा सपोर्ट नाही.</translation> <translation id="2359808026110333948">सुरू ठेवा</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">डाउनलोड पूर्ण झाले <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">कॉपी केले</translation> <translation id="2822354292072154809">तुम्हाला नक्की <ph name="CHOSEN_OBJECT_NAME" /> साठी सर्व साइट परवानग्या रीसेट करायच्या आहेत का?</translation> <translation id="2870560284913253234">साइट</translation> +<translation id="2874939134665556319">मागील ट्रॅक</translation> <translation id="2910701580606108292">सायटींना संरक्षित आशय प्ले करू देण्याआधी विचारा</translation> <translation id="2913331724188855103">कुकी डेटा सेव्ह करणे आणि वाचण्यासाठी साइटना अनुमती द्या (शिफारस केलेले)</translation> <translation id="2968755619301702150">सर्टिफिकेट दर्शक</translation> <translation id="300526633675317032">हे सर्व <ph name="SIZE_IN_KB" /> वेबसाइट स्टोरेज साफ करेल.</translation> +<translation id="301521992641321250">आपोआप ब्लॉक केलेले</translation> <translation id="3115898365077584848">माहिती दाखवा</translation> <translation id="3123473560110926937">काही साइटवर ब्लॉक केले आहे</translation> <translation id="3190152372525844641">Chrome साठी परवानग्या <ph name="BEGIN_LINK" />Android सेटिंग्ज<ph name="END_LINK" /> मध्ये सुरू करा.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">पार्श्वभूमी संकालन</translation> <translation id="3822502789641063741">साइट स्टोरेज साफ करायचे?</translation> <translation id="385051799172605136">मागील</translation> +<translation id="3859306556332390985">पुढे शोधा</translation> <translation id="3955193568934677022">संरक्षित आशय प्ले करण्यासाठी साइटना अनुमती द्या (शिफारस केलेले)</translation> <translation id="3987993985790029246">लिंक कॉपी करा</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">शीर्षक</translation> <translation id="4008040567710660924">विशिष्ट साइटसाठी कुकीना अनुमती द्या.</translation> +<translation id="4046123991198612571">पुढील ट्रॅक</translation> <translation id="4165986682804962316">साइट सेटिंग्ज</translation> <translation id="4226663524361240545">सूचनांमुळे डिव्हाइसचे कंपन होऊ शकते</translation> <translation id="4242533952199664413">सेटिंग्ज उघडा</translation> <translation id="4259722352634471385">नेव्हिगेशन अवरोधित केले आहे: <ph name="URL" /></translation> <translation id="4278390842282768270">अनुमत</translation> +<translation id="429312253194641664">साइट मीडिया प्ले करत आहे</translation> <translation id="4433925000917964731">Google द्वारे पुरवलेले लाइट पेज</translation> <translation id="4434045419905280838">पॉप-अप आणि रीडिरेक्ट</translation> <translation id="445467742685312942">साइटना संरक्षित आशय प्ले करू द्या</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">डिव्हाइससाठीच्या सर्व परवानग्या रद्द करा</translation> <translation id="4964199952259983386">Chrome ला AR वापरू देण्यासाठी, <ph name="BEGIN_LINK" />Android सेटिंग्जमध्ये<ph name="END_LINK" /> कॅमेरादेखील सुरू करा.</translation> <translation id="497421865427891073">पुढे जा</translation> +<translation id="4996978546172906250">याद्वारे शेअर करा</translation> <translation id="5039804452771397117">परवानगी द्या</translation> <translation id="5048398596102334565">साइटना मोशन सेन्सर ॲक्सेस करण्याची अनुमती द्या (शिफारस केलेले)</translation> <translation id="5063480226653192405">वापर</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">साफ करा</translation> <translation id="6697925417670533197">सुरू असलेली डाउनलोड</translation> <translation id="6746124502594467657">खाली हलवा</translation> +<translation id="6766622839693428701">बंद करण्यासाठी खाली स्वाइप करा.</translation> <translation id="6782111308708962316">तृतीय-पक्ष वेबसाइटना कुकी डेटा सेव्ह करण्यास आणि वाचण्यास प्रतिबंधित करा</translation> +<translation id="6790428901817661496">प्ले करा</translation> <translation id="6818926723028410516">आयटम निवडा</translation> <translation id="6864395892908308021">हे डिव्हाइस NFC रीड करू शकत नाही</translation> <translation id="6910211073230771657">हटवला</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">साइट तुमचा कॅमेरा वापरत आहे</translation> <translation id="7817023149356982970">तुम्हाला या साइटमधून साइन आउट केले जाईल.</translation> <translation id="7828557259026017104">कुकी म्हणजे तुम्ही भेट देता त्या वेबसाइटनी तयार केलेल्या फाइल. तुमची प्राधान्ये लक्षात ठेवण्यासाठी साइट त्यांचा वापर करतात. तृतीय पक्ष कुकी इतर साइटकडून तयार केल्या जातात. या साइटमध्ये जाहिराती किंवा इमेज यांसारखा काही आशय असतो, जो तुम्ही भेट देत असलेल्या वेबपेजवर दिसतो.</translation> +<translation id="7835852323729233924">मीडिया प्ले करत आहे</translation> <translation id="7846076177841592234">निवड रद्द करा</translation> <translation id="7846621471902887024">तुम्हाला सर्व साइटमधून साइन आउट केले जाईल.</translation> <translation id="7882806643839505685">विशिष्ट साइटसाठी ध्वनीची परवानगी द्या.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">तुम्ही कुकीजसह, सर्व स्थानिक डेटा साफ करू इच्छिता आणि या वेबसाइटसाठी सर्व परवानग्या रीसेट करू इच्छिता?</translation> <translation id="8007176423574883786">या डिव्हाइससाठी बंद करा</translation> <translation id="802154636333426148">डाउनलोड अयशस्वी झाले</translation> +<translation id="8068648041423924542">सर्टिफिकेट निवडण्यास अक्षम.</translation> <translation id="8087000398470557479">Google ने वितरित केलेली ही आशय, <ph name="DOMAIN_NAME" /> मधील आहे.</translation> <translation id="8116925261070264013">म्यूट केले</translation> <translation id="8131740175452115882">पुष्टी करा</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">साइट तुमचा कॅमेरा आणि मायक्रोफोन वापरत आहे</translation> <translation id="8380167699614421159">ही साइट अनाहूत किंवा दिशाभूल करणाऱ्या जाहिराती दाखवते</translation> <translation id="8394832520002899662">साइटवर परत जाण्यासाठी टॅप करा</translation> +<translation id="8425213833346101688">बदल करा</translation> +<translation id="8441146129660941386">मागे शोधा</translation> <translation id="8447861592752582886">डिव्हाइस परवानगी रद्द करा</translation> <translation id="8463851957836045671">साइट जलद आहे</translation> <translation id="851751545965956758">डिव्हाइसेसशी कनेक्ट करण्यापासून साइटना ब्लॉक करा</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">विशिष्ट साइटसाठी कुकी ब्लॉक करा.</translation> <translation id="8959122750345127698">नेव्हिगेशन आवाक्याबाहेर आहे: <ph name="URL" /></translation> <translation id="9019902583201351841">आपल्या पालकांद्वारे व्यवस्थापित करण्यात आले</translation> +<translation id="9074739597929991885">ब्लूटूथ</translation> <translation id="945632385593298557">तुमचा मायक्रोफोन ॲक्सेस करा</translation> <translation id="965817943346481315">साइट अनाहूत किंवा दिशाभूल करणाऱ्या जाहिराती दाखवत असल्यास ब्लॉक करा (शिफारस केलेले)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ms.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ms.xtb index 3d15ce530de..8ffe59154a3 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ms.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ms.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Seterusnya</translation> <translation id="1242008676835033345">Dibenamkan pada <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Berhenti</translation> +<translation id="1289742167380433257">Untuk menjimatkan data anda, imej halaman ini telah dioptimumkan oleh Google.</translation> <translation id="129382876167171263">Fail yang disimpan oleh tapak web akan dipaparkan di sini</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> - <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Tapak <ph name="SITE_NAME" /> telah ditambahkan</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Tanya sebelum membenarkan tapak membuat peta 3D bagi persekitaran anda atau menjejaki kedudukan kamera (disyorkan)</translation> <translation id="2212565012507486665">Benarkan kuki</translation> <translation id="2289270750774289114">Tanya apabila tapak mahu mencari peranti Bluetooth berdekatan (disyorkan)</translation> +<translation id="2315043854645842844">Pemilihan sijil pihak pelanggan tidak disokong oleh sistem pengendalian ini.</translation> <translation id="2359808026110333948">Teruskan</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">Muat turun selesai: <ph name="SEPARATOR" /><ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Disalin</translation> <translation id="2822354292072154809">Adakah anda pasti mahu menetapkan semula semua kebenaran tapak untuk <ph name="CHOSEN_OBJECT_NAME" />?</translation> <translation id="2870560284913253234">Tapak</translation> +<translation id="2874939134665556319">Lagu sebelumnya</translation> <translation id="2910701580606108292">Tanya sebelum membenarkan tapak memainkan kandungan yang dilindungi</translation> <translation id="2913331724188855103">Benarkan tapak untuk menyimpan dan membaca data kuki (disyorkan)</translation> <translation id="2968755619301702150">Pemapar sijil</translation> <translation id="300526633675317032">Tindakan ini akan menghapuskan semua <ph name="SIZE_IN_KB" /> daripada storan tapak web.</translation> +<translation id="301521992641321250">Disekat secara automatik</translation> <translation id="3115898365077584848">Tunjukkan Maklumat</translation> <translation id="3123473560110926937">Disekat di sesetengah tapak</translation> <translation id="3190152372525844641">Hidupkan kebenaran untuk Chrome dalam <ph name="BEGIN_LINK" />Tetapan Android<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Penyegerakan latar belakang</translation> <translation id="3822502789641063741">Hapuskan storan tapak?</translation> <translation id="385051799172605136">Kembali</translation> +<translation id="3859306556332390985">Cari ke hadapan</translation> <translation id="3955193568934677022">Benarkan tapak untuk memainkan kandungan yang dilindungi (disyorkan)</translation> <translation id="3987993985790029246">Salin pautan</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">Tajuk</translation> <translation id="4008040567710660924">Benarkan kuki untuk tapak tertentu.</translation> +<translation id="4046123991198612571">Lagu seterusnya</translation> <translation id="4165986682804962316">Tetapan tapak</translation> <translation id="4226663524361240545">Pemberitahuan boleh menggetarkan peranti</translation> <translation id="4242533952199664413">Buka tetapan</translation> <translation id="4259722352634471385">Navigasi disekat: <ph name="URL" /></translation> <translation id="4278390842282768270">Dibenarkan</translation> +<translation id="429312253194641664">Tapak sedang memainkan media</translation> <translation id="4433925000917964731">Halaman Lite disediakan oleh Google</translation> <translation id="4434045419905280838">Tetingkap timbul dan ubah hala</translation> <translation id="445467742685312942">Benarkan tapak memainkan kandungan yang dilindungi</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Batalkan semua kebenaran untuk peranti</translation> <translation id="4964199952259983386">Untuk membolehkan Chrome menggunakan AR, hidupkan juga kamera dalam <ph name="BEGIN_LINK" />Tetapan Android<ph name="END_LINK" />.</translation> <translation id="497421865427891073">Ke hadapan</translation> +<translation id="4996978546172906250">Kongsi melalui</translation> <translation id="5039804452771397117">Benarkan</translation> <translation id="5048398596102334565">Benarkan tapak mengakses penderia gerakan (disyorkan)</translation> <translation id="5063480226653192405">Penggunaan</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Kosongkan</translation> <translation id="6697925417670533197">Muat turun aktif</translation> <translation id="6746124502594467657">Alihkan ke bawah</translation> +<translation id="6766622839693428701">Leret ke bawah untuk tutup.</translation> <translation id="6782111308708962316">Halang tapak web pihak ketiga daripada menyimpan dan membaca data kuki</translation> +<translation id="6790428901817661496">Mainkan</translation> <translation id="6818926723028410516">Pilih item</translation> <translation id="6864395892908308021">Peranti ini tidak dapat membaca NFC</translation> <translation id="6910211073230771657">Dipadamkan</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Suatu tapak sedang menggunakan kamera anda</translation> <translation id="7817023149356982970">Anda akan dilog keluar daripada tapak ini.</translation> <translation id="7828557259026017104">Kuki ialah fail yang dibuat oleh tapak web yang anda lawati. Tapak menggunakan kuki untuk mengingat pilihan anda. Kuki pihak ketiga dibuat oleh tapak lain. Tapak ini memiliki sebahagian daripada kandungan, seperti iklan atau imej, yang anda lihat dalam halaman web yang anda lawati.</translation> +<translation id="7835852323729233924">Memainkan media</translation> <translation id="7846076177841592234">Batalkan pilihan</translation> <translation id="7846621471902887024">Anda akan dilog keluar daripada semua tapak.</translation> <translation id="7882806643839505685">Benarkan bunyi untuk tapak tertentu.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Anda pasti ingin mengosongkan semua data setempat, termasuk kuki dan menetapkan semula semua kebenaran untuk tapak web ini?</translation> <translation id="8007176423574883786">Dimatikan untuk peranti ini</translation> <translation id="802154636333426148">Muat turun gagal</translation> +<translation id="8068648041423924542">Tidak dapat memilih sijil.</translation> <translation id="8087000398470557479">Kandungan ini adalah daripada <ph name="DOMAIN_NAME" />, disampaikan oleh Google.</translation> <translation id="8116925261070264013">Diredam</translation> <translation id="8131740175452115882">Sahkan</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Suatu tapak sedang menggunakan kamera dan mikrofon anda</translation> <translation id="8380167699614421159">Tapak ini menyiarkan iklan yang mengganggu atau mengelirukan</translation> <translation id="8394832520002899662">Ketik untuk kembali ke tapak</translation> +<translation id="8425213833346101688">Tukar</translation> +<translation id="8441146129660941386">Cari ke belakang</translation> <translation id="8447861592752582886">Batalkan kebenaran peranti</translation> <translation id="8463851957836045671">Tapak laju</translation> <translation id="851751545965956758">Sekat tapak daripada menyambung ke peranti</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Sekat kuki untuk tapak tertentu.</translation> <translation id="8959122750345127698">Tidak dapat mencapai navigasi: <ph name="URL" /></translation> <translation id="9019902583201351841">Diurus oleh ibu bapa anda</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Akses mikrofon anda</translation> <translation id="965817943346481315">Sekat jika tapak menyiarkan iklan yang mengganggu atau mengelirukan (disyorkan)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_my.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_my.xtb index 7352ea3ef7c..51c599bcb11 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_my.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_my.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">ရှေ့သို့</translation> <translation id="1242008676835033345"><ph name="WEBSITE_URL" /> တွင် မြှုပ်သွင်းထားသည်</translation> <translation id="1272079795634619415">ရပ်ရန်</translation> +<translation id="1289742167380433257">ဒေတာချွေတာရန် စာမျက်နှာပါပုံများကို Google က အကောင်းဆုံးပြုပြင်ထားသည်။</translation> <translation id="129382876167171263">ဝဘ်ဆိုက်ကသိမ်းထားသော ဖိုင်များကို ဤနေရာတွင် ပြပါသည်</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> - <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">ဆိုက် <ph name="SITE_NAME" /> အား ထည့်ခဲ့၏</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">သင့်ပတ်ဝန်းကျင်၏ 3D မြေပုံဆွဲခြင်း သို့မဟုတ် ကင်မရာအနေအထား ခြေရာခံခြင်းတို့အတွက် ဝဘ်ဆိုက်များကို ခွင့်မပြုမီ မေးမြန်းရန် (အကြံပြုထားသည်)</translation> <translation id="2212565012507486665">ကွတ်ကီးများ ခွင့်ပြုရန်</translation> <translation id="2289270750774289114">ဝဘ်ဆိုက်က အနီးအနားရှိ ဘလူးတုသ်ကိရိယာများ ရှာဖွေလိုသည့်အခါ ခွင့်တောင်းရန် (အကြံပြုထားသည်)</translation> +<translation id="2315043854645842844">ကလိုင်းယင့် ဘက်မှ လက်မှတ်ရွေးမှုကို လည်ပတ်သည့်စနစ်မှ မပံ့ပိုးပါ။</translation> <translation id="2359808026110333948">ဆက်လုပ်ရန်</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> မီဂါဘိုက်</translation> <translation id="2434158240863470628">ဒေါင်းလုဒ်လုပ်ပြီးပါပြီ <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">ကူးယူပြီးပါပြီ</translation> <translation id="2822354292072154809"><ph name="CHOSEN_OBJECT_NAME" /> အတွက် ဝဘ်ဆိုက်ခွင့်ပြုချက်အားလုံးကို ပြင်ဆင်သတ်မှတ်လိုသည်မှာ သေချာသလား။</translation> <translation id="2870560284913253234">ဆိုဒ်</translation> +<translation id="2874939134665556319">ယခင်တစ်ပုဒ်</translation> <translation id="2910701580606108292">ဝဘ်ဆိုက်များအား ကာကွယ်ထားသည့် အကြောင်းအရာများကို ပြသခွင့် မပြုမီ ဦးစွာ မေးပါ</translation> <translation id="2913331724188855103">ဆိုဒ်များကို ကွက်ကီးများ ဖတ်ရန်နှင့် သိမ်းရန် ခွင့်ပြုသည် (အကြံပြုထား)</translation> <translation id="2968755619301702150">လက်မှတ်ကို ကြည့်ရှုသူ</translation> <translation id="300526633675317032">၎င်းသည် ဝဘ်ဆိုက်သိုလှောင်ခန်း၏ <ph name="SIZE_IN_KB" /> ကို ရှင်းလင်းလိုက်ပါမည်။</translation> +<translation id="301521992641321250">အလိုအလျောက် ပိတ်ထားသည်</translation> <translation id="3115898365077584848">အချက်အလက်များကို ပြသရန်</translation> <translation id="3123473560110926937">အချို့ဝဘ်ဆိုက်များတွင် ပိတ်ထားသည်</translation> <translation id="3190152372525844641">Chrome အတွက် ခွင့်ပြုချက်များကို <ph name="BEGIN_LINK" />Android ချိန်ညှိချက်များ<ph name="END_LINK" /> တွင် ဖွင့်ပါ။</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">နောက်ခံတွင် စင့်ခ်လုပ်ခြင်း</translation> <translation id="3822502789641063741">ဆိုက်နေရာကိုရှင်းမလား။</translation> <translation id="385051799172605136">နောက်သို့</translation> +<translation id="3859306556332390985">အရှေ့သို့ ရစ်ရန်</translation> <translation id="3955193568934677022">ကာကွယ်ထားသည့် အကြောင်းအရာများကို ဆိုက်များအား ဖွင့်ခွင့်ပြုပါ (အကြံပြုထားသည်)</translation> <translation id="3987993985790029246">လင့်ခ်ကူးယူမည်</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">ခေါင်းစဉ်</translation> <translation id="4008040567710660924">အချို့ဝဘ်ဆိုက်များအတွက် ကွတ်ကီးများ ခွင့်ပြုသည်။</translation> +<translation id="4046123991198612571">နောက်တစ်ပုဒ်</translation> <translation id="4165986682804962316">ဝက်ဆိုက် ဆက်တင်များ</translation> <translation id="4226663524361240545">အကြောင်းကြားချက်သည် စက်ပစ္စည်းကို တုန်ခါစေပါမည်</translation> <translation id="4242533952199664413">ဆက်တင်များကို ဖွင့်ရန်</translation> <translation id="4259722352634471385">သွားလာမှုပြလမ်းညွှန်အား ပိတ်ထား၏- <ph name="URL" /></translation> <translation id="4278390842282768270">ခွင့်ပြုထား</translation> +<translation id="429312253194641664">ဝဘ်ဆိုက်တစ်ခုက မီဒီယာကို ဖွင့်နေသည်</translation> <translation id="4433925000917964731">Google ၏ အပေါ့စား စာမျက်နှာ</translation> <translation id="4434045419905280838">ပေါ့ပ်အပ်နှင့် တစ်ဆင့်ညွှန်ချက်</translation> <translation id="445467742685312942">ကာကွယ်ထားသော အကြောင်းအရာများ ဖွင့်ရန် ဝဘ်ဆိုက်များကို� ခွင့်ပြုသည်</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">စက်ပစ္စည်းအတွက် ခွင့်ပြုချက်အားလုံး ရုပ်သိမ်းသည်</translation> <translation id="4964199952259983386">Chrome ကို AR အသုံးပြုခွင့်ပေးရန် <ph name="BEGIN_LINK" />Android ဆက်တင်များ<ph name="END_LINK" /> တွင်လည်း ကင်မရာဖွင့်ပါ။</translation> <translation id="497421865427891073">ရှေ့သို့သွား</translation> +<translation id="4996978546172906250">မှတစ်ဆင့် မျှဝေရန်</translation> <translation id="5039804452771397117">ခွင့်ပြုရန်</translation> <translation id="5048398596102334565">အာရုံခံစနစ်များ အသုံးပြုရန် ဤဝဘ်ဆိုက်များကို ခွင့်ပြုသည် (အကြံပြုထားသည်)</translation> <translation id="5063480226653192405">အသုံးပြုပုံ</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">ရှင်းရန်</translation> <translation id="6697925417670533197">လက်ရှိ ဒေါင်းလုဒ်များ</translation> <translation id="6746124502594467657">အောက်သို့ရွှေ့ပါ</translation> +<translation id="6766622839693428701">ပိတ်ရန် အောက်သို့ ပွတ်ဆွဲပါ။</translation> <translation id="6782111308708962316">ကွတ်ကီးဒေတာများကို ပြင်ပကုမ္ပဏီဝဘ်ဆိုက်များက သိမ်းဆည်းခြင်းနှင့် ဖတ်ခြင်းများ ပြုလုပ်၍မရနိုင်အောင် တားဆီးပါ</translation> +<translation id="6790428901817661496">ဖွင့်ရန်</translation> <translation id="6818926723028410516">စာရင်းမှ ရွေးရန်</translation> <translation id="6864395892908308021">ဤစက်က NFC ဖတ်၍မရပါ</translation> <translation id="6910211073230771657">ဖျက်ပြီး</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">ဝဘ်ဆိုက်တစ်ခုက သင့်ကင်မရာကို အသုံးပြုနေသည်</translation> <translation id="7817023149356982970">ဤဝဘ်ဆိုက်မှ သင် ထွက်သွားပါမည်။</translation> <translation id="7828557259026017104">ကွတ်ကီးများဟူသည်မှာ သင်ဝင်ကြည့်သည့်ဝဘ်ဆိုက်များက ပြုလုပ်ထားသော ဖိုင်များဖြစ်သည်။ ဝဘ်ဆိုက်များက ၎င်းတို့ကို အသုံးပြုပြီး သင့်ရွေးချယ်မှုများကို မှတ်သားထားသည်။ ပြင်ပကွတ်ကီးများကို အခြားဝဘ်ဆိုက်များက ပြုလုပ်ခြင်းဖြစ်သည်။ သင်ဝင်ကြည့်သည့်ဝဘ်စာမျက်နှာပေါ်တွင် တွေ့ရသည့်ကြော်ငြာ သို့မဟုတ် ပုံများကဲ့သို့သော အကြောင်းအရာအချို့ကို ဤဝဘ်ဆိုက်များက ပိုင်ဆိုင်သည်။</translation> +<translation id="7835852323729233924">မီဒီယာ ဖွင့်နေသည်</translation> <translation id="7846076177841592234">ရွေးချယ်ထားသောဖိုင်များကို ပြန်ဖျက်ပါ</translation> <translation id="7846621471902887024">ဝဘ်ဆိုက်အားလုံးမှ သင် ထွက်သွားပါမည်။</translation> <translation id="7882806643839505685">ဝဘ်ဆိုက်တစ်ခုအတွက် အသံဖွင့်ခွင့်ပြုသည်။</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">ကွက်ကီးများအပါအဝင်၊ အတွင်းရှိ ဒေတာများအားလုံး ရှင်းလင်းကာ၊ ဤဝဘ်ဆိုက်အတွက် ခွင့်ပြုချက်များအားလုံးအား ပြန်လည်သတ်မှတ်လိုသည်မှာ သေချာပါသလား?</translation> <translation id="8007176423574883786">ဤစက်ပစ္စည်းအတွက် ပိတ်ထားသည်</translation> <translation id="802154636333426148">ဒေါင်းလုဒ်လုပ်မှု မအောင်မြင်ပါ</translation> +<translation id="8068648041423924542">လက်မှတ်ကို မရွေးနိုင်ပါ။</translation> <translation id="8087000398470557479">ဤအကြောင်းအရာသည် Google မှနေ၍ပံ့ပိုးပေးထားသည့် <ph name="DOMAIN_NAME" /> မှဖြစ်သည်။</translation> <translation id="8116925261070264013">ဖျောက်ထားသည်</translation> <translation id="8131740175452115882">အတည်ပြုရန်</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">ဝဘ်ဆိုက်တစ်ခုက သင့်ကင်မရာနှင့် မိုက်ကရိုဖုန်းကို အသုံးပြုနေသည်</translation> <translation id="8380167699614421159">ဤဝဘ်ဆိုက်က စိတ်အနှောင့်အယှက်ဖြစ်စေသော (သို့) အထင်အမြင်မှားစေသော ကြော်ငြာများကို ပြသည်</translation> <translation id="8394832520002899662">ဝဘ်ဆိုက်သို့ ပြန်သွားရန် တို့ပါ</translation> +<translation id="8425213833346101688">ပြောင်းရန်</translation> +<translation id="8441146129660941386">နောက်ပြန်ရစ်ရန်</translation> <translation id="8447861592752582886">စက်ပစ္စည်းခွင့်ပြုချက်ကို ရုပ်သိမ်းပါ</translation> <translation id="8463851957836045671">ဝဘ်ဆိုက်က မြန်သည်</translation> <translation id="851751545965956758">စက်သို့ ဝဘ်ဆိုက်များ ချိတ်ဆက်ခြင်းကို ပိတ်ထားသည်</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">အချို့ဝဘ်ဆိုက်များအတွက် ကွတ်ကီးများကို ပိတ်ဆို့သည်။</translation> <translation id="8959122750345127698">သွားလာမှုပြလမ်းညွှန်ဆီသို့ မရောက်နိုင်ပါ- <ph name="URL" /></translation> <translation id="9019902583201351841">သင့်မိဘများမှ စီမံသည်</translation> +<translation id="9074739597929991885">ဘလူးတုသ်</translation> <translation id="945632385593298557">သင့်မိုက်အား အသုံးပြုမည်</translation> <translation id="965817943346481315">စိတ်အနှောင့်အယှက်ဖြစ်စေသော (သို့) အထင်အမြင်မှားစေသော ကြော်ငြာများ ပြလျှင် ဝဘ်ဆိုက်ကို ပိတ်သည် (အကြံပြုထားသည်)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ne.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ne.xtb index d35588602e3..dd6d6ab2a4d 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ne.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ne.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">अर्को</translation> <translation id="1242008676835033345"><ph name="WEBSITE_URL" /> मा इम्बेड गरिएको</translation> <translation id="1272079795634619415">रोक्नुहोस्</translation> +<translation id="1289742167380433257">तपाईंको डेटाको खपत कम गर्न Google ले यो पृष्ठका फोटोहरू अप्टिमाइज गरेको छ।</translation> <translation id="129382876167171263">वेबसाइटहरूले सुरक्षित गरेका फाइल यहाँ देखिने छन्</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> - <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">साइट <ph name="SITE_NAME" /> थपियो</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">साइटहरूलाई आफू वरपरको ठाउँको 3D नक्सा बनाउन वा क्यामेराको अवस्था पत्ता लगाउन दिनुअघि मलाई सोधियोस् (सिफारिस गरिएको)</translation> <translation id="2212565012507486665">कुकीहरूलाई अनुमति दिनुहोस्</translation> <translation id="2289270750774289114">कुनै साइटले छेउछाउका ब्लुटुथ यन्त्रहरू पत्ता लगाउन खोज्दा सोध्नुहोस् (सिफारिस गरिएको)</translation> +<translation id="2315043854645842844">अपरेटिङ सिस्टमले क्लाइन्ट साइड प्रमाणपत्रको चयनलाई समर्थन गर्दैन।</translation> <translation id="2359808026110333948">जारी राख्नुहोस्</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> एम.बि.</translation> <translation id="2434158240863470628">डाउनलोड सम्पन्न भयो <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">प्रतिलिपि गरियो</translation> <translation id="2822354292072154809">तपाईं साँच्चिकै <ph name="CHOSEN_OBJECT_NAME" /> का साइटसम्बन्धी सम्पूर्ण अनुमतिहरू रिसेट गर्न चाहनुहुन्छ?</translation> <translation id="2870560284913253234">साइट</translation> +<translation id="2874939134665556319">अघिल्लो ट्र्याक</translation> <translation id="2910701580606108292">साइटहरूलाई संरक्षित सामग्री प्ले गर्ने अनुमति दिनुअघि सोध्नुहोस्</translation> <translation id="2913331724188855103">साइटहरूलाई कुकी डेटा सुरक्षित गर्ने र पढ्ने अनुमति दिनुहोस् (सिफारिस गरिएको)</translation> <translation id="2968755619301702150">प्रमाणपत्र दर्शक</translation> <translation id="300526633675317032">यसले वेबसाइटको भण्डारणको सबै <ph name="SIZE_IN_KB" /> खाली गर्ने छ।</translation> +<translation id="301521992641321250">स्वतः रोक लगाइयो</translation> <translation id="3115898365077584848">जानकारी देखाउनुहोस्</translation> <translation id="3123473560110926937">केही साइटका हकमा रोक लगाइएको छ</translation> <translation id="3190152372525844641"><ph name="BEGIN_LINK" /> Android सेटिङहरू <ph name="END_LINK" /> मा Chrome का लागि अनुमतिहरू सक्रिय गर्नुहोस् ।</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">पृष्ठभूमिमा सिंक गर्ने सुविधा</translation> <translation id="3822502789641063741">साइटको भण्डारणलई खाली गर्ने हो?</translation> <translation id="385051799172605136">पछाडि जानुहोस्</translation> +<translation id="3859306556332390985">अगाडि खोज्नुहोस्</translation> <translation id="3955193568934677022">साइटहरूलाई सुरक्षित सामग्री प्ले गर्न अनुमति दिनुहोस् (सिफारिस गरिएको)</translation> <translation id="3987993985790029246">लिंक प्रतिलिपि गर्नुहोस्</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">शीर्षक</translation> <translation id="4008040567710660924">कुनै खास साइटमा कुकीहरूलाई अनुमति दिनुहोस्।</translation> +<translation id="4046123991198612571">अर्को ट्र्याक</translation> <translation id="4165986682804962316">साइट सेटिङहरू</translation> <translation id="4226663524361240545">सूचनाहरूले गर्दा यन्त्र कम्पन गर्न सक्छ</translation> <translation id="4242533952199664413">सेटिङहरू खोल्नुहोस्</translation> <translation id="4259722352634471385">नेभिगेशन रोकियो: <ph name="URL" /></translation> <translation id="4278390842282768270">अनुमति प्राप्त</translation> +<translation id="429312253194641664">कुनै साइटले मिडियो प्ले गरिरहेको छ</translation> <translation id="4433925000917964731">Google ले प्रदान गरेको मूल पृष्ठको लाइट संस्करण</translation> <translation id="4434045419905280838">पपअप तथा रिडिरेक्टहरू</translation> <translation id="445467742685312942">साइटहरूलाई संरक्षित सामग्री प्ले गर्ने अनुमति दिनुहोस्</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">यन्त्रका सबै अनुमतिहरू फिर्ता लिनुहोस्</translation> <translation id="4964199952259983386">Chrome लाई AR प्रयोग गर्न दिन <ph name="BEGIN_LINK" />Android का सेटिङ<ph name="END_LINK" />मा गई क्यामेरा पनि सुचारु गर्नुहोस्।</translation> <translation id="497421865427891073">अगाडि जानुहोस्</translation> +<translation id="4996978546172906250">मार्फत साझा गर्नुहोस्</translation> <translation id="5039804452771397117">अनुमति दिनुहोस्</translation> <translation id="5048398596102334565">साइटहरूलाई चालसम्बन्धी सेन्सरहरूमाथि पहुँच राख्ने अनुमति दिनुहोस् (सिफारिस गरिएको)</translation> <translation id="5063480226653192405">उपयोग</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">खालि गर्नुहोस्</translation> <translation id="6697925417670533197">जारी डाउनलोडहरू</translation> <translation id="6746124502594467657">तल सार्नुहोस्</translation> +<translation id="6766622839693428701">बन्द गर्न तलतिर स्वाइप गर्नुहोस्।</translation> <translation id="6782111308708962316">तेस्रो पक्षीय वेबसाइटहरूलाई कुकी सम्बन्धी डेटा सुरक्षित गर्न र पढ्न नदिनुहोस्</translation> +<translation id="6790428901817661496">प्ले गर्नुहोस्</translation> <translation id="6818926723028410516">वस्तुहरू छनाैट गर्नुहोस्</translation> <translation id="6864395892908308021">यस यन्त्रले NFC पढ्न सक्दैन</translation> <translation id="6910211073230771657">मेटाइएको</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">कुनै साइटले तपाईंको क्यामेरा प्रयोग गर्दै छ</translation> <translation id="7817023149356982970">तपाईं यो साइटबाट साइन आउट हुनु हुने छ।</translation> <translation id="7828557259026017104">कुकीहरू भनेका तपाईं जाने वेबसाइटहरूले सिर्जना गर्ने फाइल हुन्। तपाईंका प्राथमिकताहरू याद राख्न वेबसाइटहरूले ती कुकीहरूको प्रयोग गर्छन्। अन्य वेबसाइटहरूले तेस्रो पक्षीय कुकीहरू सिर्जना गर्छन्। तपाईं जाने वेबपृष्ठमा तपाईंले देख्ने विज्ञापन वा छविहरू जस्ता केही सामग्री यी वेबसाइटहरूको स्वामित्वमा हुन्छन्।</translation> +<translation id="7835852323729233924">प्ले भइरहेको मिडिया</translation> <translation id="7846076177841592234">चयन रद्द गर्नुहोस्</translation> <translation id="7846621471902887024">तपाईं सबै साइटहरूबाट साइन आउट हुनु हुने छ।</translation> <translation id="7882806643839505685">निश्चित साइटको ध्वनिलाई अनुमति दिनुहोस्।</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">के तपाईं कुकीहरू सहित सबै स्थानीय डेटा खाली गर्न चाहनुहुन्छ, र यो वेबसाइटको लागि सबै अनुमतिहरू रिसेट गर्न चाहनुहुन्छ?</translation> <translation id="8007176423574883786">यस यन्त्रका लागि बन्द गरियो।</translation> <translation id="802154636333426148">डाउनलोड गर्न सकिएन</translation> +<translation id="8068648041423924542">प्रमाणपत्र चयन गर्न असमर्थ।</translation> <translation id="8087000398470557479">यो Google द्वारा डेलिभर गरिएको <ph name="DOMAIN_NAME" /> को सामग्री हो।</translation> <translation id="8116925261070264013">म्युट गरियो</translation> <translation id="8131740175452115882">निश्चित</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">कुनै साइटले तपाईंको क्यामेरा र माइक्रोफोन प्रयोग गर्दै छ</translation> <translation id="8380167699614421159">यो साइटले हस्तक्षेपकारी वा भ्रामक विज्ञापनहरू देखाउँछ</translation> <translation id="8394832520002899662">साइटमा फर्कन ट्याप गर्नुहोस्</translation> +<translation id="8425213833346101688">परिवर्तन गर्नुहोस्</translation> +<translation id="8441146129660941386">पछाडि खोज्नुहोस्</translation> <translation id="8447861592752582886">यन्त्र सम्बन्धी अनुमतिलाई उल्टाउनुहोस्</translation> <translation id="8463851957836045671">साइट द्रूत छ</translation> <translation id="851751545965956758">साइटहरूलाई यन्त्रमा जडान गर्नबाट रोक लगाउनुहोस्</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">कुनै खास साइटमा कुकीहरूलाई रोक लगाउनुहोस्।</translation> <translation id="8959122750345127698">नेभिगेशन पहुँचयोग्य छैन: <ph name="URL" /></translation> <translation id="9019902583201351841">तपाईँको अविभावक द्वारा व्यवस्थित</translation> +<translation id="9074739597929991885">ब्लुटुथ</translation> <translation id="945632385593298557">आफ्नो माइक्रोफोन पहुँच गर्नुहोस्</translation> <translation id="965817943346481315">साइटले हस्तक्षेपकारी वा भ्रामक विज्ञापनहरू देखाएमा त्यसलाई रोक लगाउनुहोस् (सिफारिस गरिएको)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_nl.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_nl.xtb index d80b5d40411..6efd0126edc 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_nl.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_nl.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Volgende</translation> <translation id="1242008676835033345">Ingesloten in <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Stop</translation> +<translation id="1289742167380433257">De afbeeldingen op deze pagina zijn door Google geoptimaliseerd om data te besparen.</translation> <translation id="129382876167171263">Bestanden die worden opgeslagen door websites, worden hier weergegeven</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> - <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Site <ph name="SITE_NAME" /> toegevoegd</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Vragen voordat sites een 3D-kaart van je omgeving mogen maken of de camerapositie mogen volgen (aanbevolen)</translation> <translation id="2212565012507486665">Cookies toestaan</translation> <translation id="2289270750774289114">Vragen wanneer een site Bluetooth-apparaten in de buurt wilt detecteren (aanbevolen)</translation> +<translation id="2315043854645842844">Certificaatselectie aan clientzijde wordt niet ondersteund door het besturingssysteem.</translation> <translation id="2359808026110333948">Doorgaan</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">Download voltooid <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Gekopieerd</translation> <translation id="2822354292072154809">Weet je zeker dat je alle siterechten voor <ph name="CHOSEN_OBJECT_NAME" /> wilt resetten?</translation> <translation id="2870560284913253234">Site</translation> +<translation id="2874939134665556319">Vorig nummer</translation> <translation id="2910701580606108292">Vragen voordat sites beschermde content mogen afspelen</translation> <translation id="2913331724188855103">Sites toestaan cookiegegevens op te slaan en te lezen (aanbevolen)</translation> <translation id="2968755619301702150">Certificaatviewer</translation> <translation id="300526633675317032">Hiermee wordt de volledige <ph name="SIZE_IN_KB" /> aan site-opslag gewist.</translation> +<translation id="301521992641321250">Automatisch geblokkeerd</translation> <translation id="3115898365077584848">Informatie weergeven</translation> <translation id="3123473560110926937">Geblokkeerd op bepaalde sites</translation> <translation id="3190152372525844641">Schakel rechten in voor Chrome via de <ph name="BEGIN_LINK" />Android-instellingen<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Synchronisatie op de achtergrond</translation> <translation id="3822502789641063741">Site-opslag wissen?</translation> <translation id="385051799172605136">Terug</translation> +<translation id="3859306556332390985">Vooruit zoeken</translation> <translation id="3955193568934677022">Toestaan dat sites beschermde content afspelen (aanbevolen)</translation> <translation id="3987993985790029246">Link kop.</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> van ?</translation> <translation id="4002066346123236978">Titel</translation> <translation id="4008040567710660924">Cookies voor een specifieke site toestaan.</translation> +<translation id="4046123991198612571">Volgend nummer</translation> <translation id="4165986682804962316">Site-instellingen</translation> <translation id="4226663524361240545">Het apparaat kan trillen bij meldingen</translation> <translation id="4242533952199664413">Instellingen openen</translation> <translation id="4259722352634471385">Navigatie is geblokkeerd: <ph name="URL" /></translation> <translation id="4278390842282768270">Toegestaan</translation> +<translation id="429312253194641664">Een site speelt media af</translation> <translation id="4433925000917964731">Lite-pagina geleverd door Google</translation> <translation id="4434045419905280838">Pop-ups en omleidingen</translation> <translation id="445467742685312942">Sites toestaan om beschermde content af te spelen</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Alle rechten voor apparaat intrekken</translation> <translation id="4964199952259983386">Schakel ook de camera in via de <ph name="BEGIN_LINK" />Android-instellingen<ph name="END_LINK" /> als je Chrome AR wilt laten gebruiken.</translation> <translation id="497421865427891073">Naar voren gaan</translation> +<translation id="4996978546172906250">Delen via</translation> <translation id="5039804452771397117">Toestaan</translation> <translation id="5048398596102334565">Sites toegang geven tot bewegingssensoren (aanbevolen)</translation> <translation id="5063480226653192405">Gebruik</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Wissen</translation> <translation id="6697925417670533197">Actieve downloads</translation> <translation id="6746124502594467657">Omlaag</translation> +<translation id="6766622839693428701">Swipe omlaag om te sluiten.</translation> <translation id="6782111308708962316">Voorkomen dat websites van derden cookiegegevens opslaan en lezen</translation> +<translation id="6790428901817661496">Spelen</translation> <translation id="6818926723028410516">Items selecteren</translation> <translation id="6864395892908308021">Dit apparaat kan NFC niet lezen</translation> <translation id="6910211073230771657">Verwijderd</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Een site gebruikt de camera</translation> <translation id="7817023149356982970">Je wordt uitgelogd van deze site.</translation> <translation id="7828557259026017104">Cookies zijn bestanden die worden gemaakt door websites die je bezoekt. Sites gebruiken ze om je voorkeuren te onthouden. Cookies van derden worden gemaakt door andere sites. Deze sites zijn eigenaar van een deel van de content (zoals advertenties of afbeeldingen) die je ziet op de webpagina die je bezoekt.</translation> +<translation id="7835852323729233924">Media afspelen</translation> <translation id="7846076177841592234">Selectie opheffen</translation> <translation id="7846621471902887024">Je wordt uitgelogd van alle sites.</translation> <translation id="7882806643839505685">Geluid toestaan voor een specifieke site.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Weet je zeker dat je alle gegevens, inclusief cookies, voor deze website wilt wissen en alle rechten opnieuw wilt instellen?</translation> <translation id="8007176423574883786">Uitgeschakeld voor dit apparaat</translation> <translation id="802154636333426148">Downloaden mislukt</translation> +<translation id="8068648041423924542">Kan certificaat niet selecteren.</translation> <translation id="8087000398470557479">Deze content is afkomstig van <ph name="DOMAIN_NAME" />, geleverd door Google.</translation> <translation id="8116925261070264013">Gedempt</translation> <translation id="8131740175452115882">Bevestigen</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Een site gebruikt de camera en microfoon</translation> <translation id="8380167699614421159">Deze site geeft opdringerige of misleidende advertenties weer</translation> <translation id="8394832520002899662">Tik hier om terug te gaan naar de site</translation> +<translation id="8425213833346101688">Wijzigen</translation> +<translation id="8441146129660941386">Achteruit zoeken</translation> <translation id="8447861592752582886">Rechten voor apparaat intrekken</translation> <translation id="8463851957836045671">Site is snel</translation> <translation id="851751545965956758">Voorkomen dat sites verbinding maken met apparaten</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Cookies voor een specifieke site blokkeren.</translation> <translation id="8959122750345127698">Navigatie is onbereikbaar: <ph name="URL" /></translation> <translation id="9019902583201351841">Beheerd door je ouders</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Toegang tot je microfoon</translation> <translation id="965817943346481315">Blokkeren als site opdringerige of misleidende advertenties weergeeft (aanbevolen)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_no.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_no.xtb index 6522c94b138..bc3e7e58b35 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_no.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_no.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Neste</translation> <translation id="1242008676835033345">Innebygd på <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Stopp</translation> +<translation id="1289742167380433257">For å spare data er bildene på denne siden optimalisert av Google.</translation> <translation id="129382876167171263">Filer som nettsteder har lagret, vises her</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> – <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Nettstedet <ph name="SITE_NAME" /> er lagt til</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Spør før nettsteder får lage 3D-kart av omgivelsene dine eller spore kameraposisjonen (anbefales)</translation> <translation id="2212565012507486665">Tillat informasjonskapsler</translation> <translation id="2289270750774289114">Spør når nettsteder vil oppdage Bluetooth-enheter i nærheten (anbefales)</translation> +<translation id="2315043854645842844">Operativsystemet har ikke støtte for sertifikatvalg på klientsiden.</translation> <translation id="2359808026110333948">Fortsett</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">Nedlasting fullført <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Kopiert</translation> <translation id="2822354292072154809">Er du sikker på at du vil tilbakestille alle nettstedstillatelser for <ph name="CHOSEN_OBJECT_NAME" />?</translation> <translation id="2870560284913253234">Nettsted</translation> +<translation id="2874939134665556319">Forrige spor</translation> <translation id="2910701580606108292">Spør før nettsteder kan spille av beskyttet innhold</translation> <translation id="2913331724188855103">Tillat at nettsteder lagrer og leser data i informasjonskapsler (anbefales)</translation> <translation id="2968755619301702150">Visningsprogram for sertifikater</translation> <translation id="300526633675317032">Dette sletter alle dataene (<ph name="SIZE_IN_KB" />) fra nettstedslagringen.</translation> +<translation id="301521992641321250">Automatisk blokkert</translation> <translation id="3115898365077584848">Vis informasjon</translation> <translation id="3123473560110926937">Blokkert på enkelte nettsteder</translation> <translation id="3190152372525844641">Slå på tillatelsene for Chrome i <ph name="BEGIN_LINK" />Android-innstillingene<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Bakgrunnssynkronisering</translation> <translation id="3822502789641063741">Slette nettstedslagring?</translation> <translation id="385051799172605136">Tilbake</translation> +<translation id="3859306556332390985">Spol fremover</translation> <translation id="3955193568934677022">Gi nettsteder tillatelse til å spille av beskyttet innhold (anbefales)</translation> <translation id="3987993985790029246">Kopiér link</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">Tittel</translation> <translation id="4008040567710660924">Tillat informasjonskapsler for et spesifikt nettsted.</translation> +<translation id="4046123991198612571">Neste spor</translation> <translation id="4165986682804962316">Nettstedsinnstillinger</translation> <translation id="4226663524361240545">Varsler kan gjøre at enheten vibrerer</translation> <translation id="4242533952199664413">Åpne innstillingene</translation> <translation id="4259722352634471385">Nettadressen er blokkert: <ph name="URL" /></translation> <translation id="4278390842282768270">Tillatt</translation> +<translation id="429312253194641664">Et nettsted spiller av medier</translation> <translation id="4433925000917964731">Forenklet versjon av siden levert av Google</translation> <translation id="4434045419905280838">Forgrunnsvinduer/viderekoblinger</translation> <translation id="445467742685312942">Tillat at nettsteder kan spille beskyttet innhold</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Opphev alle tillatelser for enheten</translation> <translation id="4964199952259983386">For å la Chrome bruke AR, slå på kameraet i <ph name="BEGIN_LINK" />Android-innstillingene<ph name="END_LINK" /> også.</translation> <translation id="497421865427891073">Gå til neste</translation> +<translation id="4996978546172906250">Del via</translation> <translation id="5039804452771397117">Tillat</translation> <translation id="5048398596102334565">Gi nettsteder tilgang til bevegelsessensorer (anbefalt)</translation> <translation id="5063480226653192405">Bruk</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Tøm</translation> <translation id="6697925417670533197">Aktive nedlastinger</translation> <translation id="6746124502594467657">Flytt ned</translation> +<translation id="6766622839693428701">Sveip ned for å lukke.</translation> <translation id="6782111308708962316">Forhindrer at nettsteder fra tredjeparter lagrer og leser data i informasjonskapsler</translation> +<translation id="6790428901817661496">Spill av</translation> <translation id="6818926723028410516">Velg elementer</translation> <translation id="6864395892908308021">Denne enheten kan ikke lese NFC</translation> <translation id="6910211073230771657">Slettet</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Et nettsted bruker kameraet ditt</translation> <translation id="7817023149356982970">Du blir logget av dette nettstedet.</translation> <translation id="7828557259026017104">Informasjonskapsler er filer som opprettes av nettsteder du besøker. Nettsteder bruker dem til å huske preferansene dine. Informasjonskapsler fra tredjeparter opprettes av andre nettsteder. Disse nettstedene eier noe av innholdet, for eksempel annonser eller bilder, som du ser på nettsiden du besøker.</translation> +<translation id="7835852323729233924">Spiller av medier</translation> <translation id="7846076177841592234">Opphev valget</translation> <translation id="7846621471902887024">Du blir logget av alle nettsteder.</translation> <translation id="7882806643839505685">Tillat lyd for et bestemt nettsted.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Er du sikker på at du vil slette alle lokale data, deriblant informasjonskapsler, og tilbakestille alle tillatelser for dette nettstedet?</translation> <translation id="8007176423574883786">Slått av for denne enheten</translation> <translation id="802154636333426148">Nedlastingen mislyktes</translation> +<translation id="8068648041423924542">Kan ikke velge sertifikat.</translation> <translation id="8087000398470557479">Dette innholdet er fra <ph name="DOMAIN_NAME" /> og er levert av Google.</translation> <translation id="8116925261070264013">Kuttet lyd</translation> <translation id="8131740175452115882">Bekreft</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Et nettsted bruker kameraet ditt og mikrofonen din</translation> <translation id="8380167699614421159">Dette nettstedet viser forstyrrende eller villedende annonser</translation> <translation id="8394832520002899662">Trykk for å gå tilbake til nettstedet</translation> +<translation id="8425213833346101688">Endre</translation> +<translation id="8441146129660941386">Spol bakover</translation> <translation id="8447861592752582886">Opphev tillatelsen til enhetstilgang</translation> <translation id="8463851957836045671">Nettstedet er raskt</translation> <translation id="851751545965956758">Blokkér at nettsteder kobler til enheter</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Blokkér informasjonskapsler for et spesifikt nettsted.</translation> <translation id="8959122750345127698">Nettadressen er utilgjengelig: <ph name="URL" /></translation> <translation id="9019902583201351841">Administrert av foreldrene dine</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Tilgang til mikrofonen din</translation> <translation id="965817943346481315">Blokkér hvis nettstedet viser forstyrrende eller villedende annonser (anbefalt)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_or.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_or.xtb index 3b6ae16fef4..00797b8282c 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_or.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_or.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">ପରବର୍ତ୍ତୀ</translation> <translation id="1242008676835033345"><ph name="WEBSITE_URL" />ରେ ଏମ୍ବେଡ୍ କରାଯାଇଛି</translation> <translation id="1272079795634619415">ବନ୍ଦ କରନ୍ତୁ</translation> +<translation id="1289742167380433257">ଆପଣଙ୍କ ଡାଟା ସେଭ୍ କରିବା ପାଇଁ, Google ଏହି ପୃଷ୍ଠାର ଛବିଗୁଡ଼ିକୁ ଅପ୍ଟିମାଇଜ୍ କରିଛି।</translation> <translation id="129382876167171263">ୱେବ୍ସାଇଟ୍ଗୁଡ଼ିକ ଦ୍ୱାରା ସେଭ୍ କରାଯାଇଥିବା ଫାଇଲ୍ଗୁଡ଼ିକ ଏଠାରେ ଦେଖାଯାଏ</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> - <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676"><ph name="SITE_NAME" /> ସାଇଟ୍ ଯୋଗ କରାଗଲା</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">ଆପଣଙ୍କ ପରିପାର୍ଶ୍ୱର ଏକ 3D ମ୍ୟାପ୍ ତିଆରି କରିବା ଏବଂ କ୍ୟାମେରା ସ୍ଥିତି ଟ୍ରାକ୍ କରିବାକୁ ସାଇଟଗୁଡ଼ିକୁ ଅନୁମତି ଦେବା ପୂର୍ବରୁ ପଚାରନ୍ତୁ (ସୁପାରିଶ କରାଯାଇଛି)</translation> <translation id="2212565012507486665">କୁକୀଗୁଡ଼ିକୁ ଅନୁମତି ଦିଅନ୍ତୁ</translation> <translation id="2289270750774289114">ଯେତେବେଳେ ଏକ ସାଇଟ୍ ଆଖପାଖର ବ୍ଲୁଟୂଥ୍ ଡିଭାଇସ୍ଗୁଡ଼ିକୁ ଖୋଜିବାକୁ ଚାହୁଁଛି, ସେତେବେଳେ ପଚାରନ୍ତୁ (ସୁପାରିଶ କରାଯାଇଛି)</translation> +<translation id="2315043854645842844">କ୍ଲାଏଣ୍ଟ ସାଇଡ୍ ସାର୍ଟିଫିକେଟ୍ ଚୟନ ଅପରେଟିଂ ସିଷ୍ଟମ୍ ଦ୍ବାରା ସପୋର୍ଟ କରୁନାହିଁ।</translation> <translation id="2359808026110333948">ଜାରି ରଖନ୍ତୁ</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">ଡାଉନ୍ଲୋଡ୍ ଶେଷ ହେଲା <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">କପି କରାଯାଇଛି</translation> <translation id="2822354292072154809">ଆପଣ କ’ଣ ନିଶ୍ଚିତ ଯେ ଆପଣ <ph name="CHOSEN_OBJECT_NAME" /> ପାଇଁ ସମସ୍ତ ସାଇଟ୍ ଅନୁମତିଗୁଡ଼ିକ ଚାହୁଁଛନ୍ତି?</translation> <translation id="2870560284913253234">ସାଇଟ୍</translation> +<translation id="2874939134665556319">ପୂର୍ବବର୍ତ୍ତୀ ଟ୍ରାକ୍</translation> <translation id="2910701580606108292">ସାଇଟ୍ଗୁଡ଼ିକୁ ସୁରକ୍ଷିତ ବିଷୟବସ୍ତୁ ଚଲାଇବା ପାଇଁ ଅନୁମତି ଦେବା ପୂର୍ବରୁ, ପଚାରନ୍ତୁ</translation> <translation id="2913331724188855103">କୁକୀ ଡାଟାଗୁଡ଼ିକୁ ସେଭ୍ କରିବାକୁ ଏବଂ ପଢ଼ିବା ପାଇଁ ସାଇଟ୍ଗୁଡ଼ିକୁ ଅନୁମତି ଦିଅନ୍ତୁ (ସୁପାରିଶ୍ କରାଯାଇଛି)</translation> <translation id="2968755619301702150">ସାର୍ଟିଫିକେଟ୍ ଭ୍ୟୁଅର୍</translation> <translation id="300526633675317032">ଏହା ୱେବ୍ସାଇଟ୍ ଷ୍ଟୋରେଜ୍ର ସମସ୍ତ <ph name="SIZE_IN_KB" /> ଡାଟା ଖାଲି କରିବ।</translation> +<translation id="301521992641321250">ସ୍ୱଚାଳିତ ଭାବେ ବ୍ଲକ୍ କରାଗଲା</translation> <translation id="3115898365077584848">ସୂଚନା ଦେଖାନ୍ତୁ</translation> <translation id="3123473560110926937">କିଛି ସାଇଟ୍ଗୁଡ଼ିକରେ ଅବରୋଧ କରାଯାଇଛି</translation> <translation id="3190152372525844641"><ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />ରେ Chrome ପାଇଁ ଅନୁମତି ଚାଲୁ କରନ୍ତୁ।</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">ପୃଷ୍ଠପଟ ସିଙ୍କ୍</translation> <translation id="3822502789641063741">ସାଇଟ୍ ଷ୍ଟୋରେଜ୍ ଖାଲି କରିବେ?</translation> <translation id="385051799172605136">ପଛକୁ</translation> +<translation id="3859306556332390985">ଆଗକୁ ବଢ଼ାନ୍ତୁ</translation> <translation id="3955193568934677022">ସୁରକ୍ଷିତ ବିଷୟବସ୍ତୁକୁ ଚଲାଇବା ପାଇଁ ସାଇଟ୍ଗୁଡ଼ିକୁ ଅନୁମତି ଦିଆଯାଇଛି।(ସୁପାରିଶ୍ କରାଯାଇଛି)</translation> <translation id="3987993985790029246">ଲିଙ୍କ୍ କପି କରନ୍ତୁ</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">ଆଖ୍ୟା</translation> <translation id="4008040567710660924">ଏକ ନିର୍ଦ୍ଦିଷ୍ଟ ସାଇଟ୍ ପାଇଁ କୁକୀଗୁଡ଼ିକୁ ଅନୁମତି ଦିଏ।</translation> +<translation id="4046123991198612571">ପରବର୍ତ୍ତୀ ଟ୍ରାକ୍</translation> <translation id="4165986682804962316">ସାଇଟ୍ ସେଟିଂସ୍</translation> <translation id="4226663524361240545">ବିଜ୍ଞପ୍ତି ଡିଭାଇସ୍କୁ ଭାଇବ୍ରେଟ୍ କରିପାରେ</translation> <translation id="4242533952199664413">ସେଟିଂସ୍ ଖୋଲନ୍ତୁ</translation> <translation id="4259722352634471385">ନାଭିଗେସନ୍ ଅବରୋଧ କରାଯାଇଛି: <ph name="URL" /></translation> <translation id="4278390842282768270">ଅନୁମୋଦିତ</translation> +<translation id="429312253194641664">କୌଣସି ସାଇଟ୍ ମିଡିଆ ଚଲାଉଛି</translation> <translation id="4433925000917964731">Google ଦ୍ୱାରା ପ୍ରଦତ୍ତ ଲାଇଟ୍ ପୃଷ୍ଠା</translation> <translation id="4434045419905280838">ପପ୍-ଅପ୍ ଏବଂ ରିଡାଇରେକ୍ଟ</translation> <translation id="445467742685312942">ସାଇଟ୍ଗୁଡ଼ିକୁ ସୁରକ୍ଷିତ ବିଷୟବସ୍ତୁ ଚଳାଇବାକୁ ଅନୁମତି ଦିଅନ୍ତୁ</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">ଡିଭାଇସ୍ପାଇଁ ଥିବା ସମସ୍ତ ଅନୁମତିଗୁଡ଼ିକ ପ୍ରତ୍ୟାହାର କରନ୍ତୁ</translation> <translation id="4964199952259983386">Chromeକୁ AR ବ୍ୟବହାର କରିବାକୁ ଦେବା ନିମନ୍ତେ, <ph name="BEGIN_LINK" />Android ସେଟିଂସ<ph name="END_LINK" />ରେ କ୍ୟାମେରା ମଧ୍ୟ ଚାଲୁ କରନ୍ତୁ।</translation> <translation id="497421865427891073">ଆଗକୁ ଯାଆନ୍ତୁ</translation> +<translation id="4996978546172906250">ଏହା ମାଧ୍ୟମରେ ସେୟାର୍ କରନ୍ତୁ</translation> <translation id="5039804452771397117">ଅନୁମତି</translation> <translation id="5048398596102334565">ମୋସନ୍ ସେନ୍ସର୍ ଆକ୍ସେସ୍ କରିବାକୁ ସାଇଟ୍ଗୁଡ଼ିକୁ ଅନୁମତି ଦିଅନ୍ତୁ (ସୁପାରିଶ କରାଯାଇଛି)</translation> <translation id="5063480226653192405">ବ୍ୟବହାର</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">ଖାଲି କରନ୍ତୁ</translation> <translation id="6697925417670533197">ସକ୍ରିୟ ଡାଉନଲୋଡଗୁଡ଼ିକ</translation> <translation id="6746124502594467657">ତଳକୁ ଚାଳନ କରନ୍ତୁ</translation> +<translation id="6766622839693428701">ବନ୍ଦ କରିବା ପାଇଁ ତଳକୁ ସ୍ଵାଇପ୍ କରନ୍ତୁ</translation> <translation id="6782111308708962316">ଡାଟା ସେଭ୍ କରିବା ଏବଂ ପଢ଼ିବାରୁ ତୃତୀୟ ପକ୍ଷ ୱେବ୍ସାଇଟ୍ଗୁଡ଼ିକୁ ନିବୃତ୍ତ କରେ</translation> +<translation id="6790428901817661496">ଚଲାନ୍ତୁ</translation> <translation id="6818926723028410516">ଆଇଟମ୍ ଚୟନ କରନ୍ତୁ</translation> <translation id="6864395892908308021">ଏହି ଡିଭାଇସ୍ NFC ପଢ଼ିପାରିବ ନାହିଁ</translation> <translation id="6910211073230771657">ଡିଲିଟ୍ କରାଗଲା</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">କୌଣସି ସାଇଟ୍ ଆପଣଙ୍କ କ୍ୟାମେରା ବ୍ୟବହାର କରୁଛି</translation> <translation id="7817023149356982970">ଏହି ସାଇଟରୁ ଆପଣଙ୍କୁ ସାଇନ୍ ଆଉଟ୍ କରିଦିଆଯିବ।</translation> <translation id="7828557259026017104">କୁକୀଗୁଡ଼ିକ ହେଉଛି ଆପଣ ୱେବସାଇଟଗୁଡ଼ିକୁ ଭିଜିଟ୍ କଲେ ତିଆରି ହେଉଥିବା ଫାଇଲଗୁଡ଼ିକ। ଆପଣଙ୍କ ପସନ୍ଦଗୁଡ଼ିକ ମନେରଖିବାକୁ ସାଇଟଗୁଡ଼ିକ ସେଗୁଡ଼ିକୁ ବ୍ୟବହାର କରେ। ଅନ୍ୟ ସାଇଟଗୁଡ଼ିକ ଦ୍ୱାରା ତୃତୀୟ-ପକ୍ଷ କୁକୀଗୁଡ଼ିକ ତିଆରି କରାଯାଇଛି। ବିଜ୍ଞାପନ କିମ୍ବା ଛବିଗୁଡ଼ିକ ପରି କିଛି ବିଷୟବସ୍ତୁ ଉପରେ ଏହି ସାଇଟଗୁଡ଼ିକର ମାଲିକାନା ଅଛି, ଯାହାକୁ ଆପଣ ଭିଜିଟ୍ କରୁଥିବା ୱେବପୃଷ୍ଠାରେ ଦେଖନ୍ତି।</translation> +<translation id="7835852323729233924">ମିଡିଆ ପ୍ଲେ ହେଉଛି</translation> <translation id="7846076177841592234">ଚୟନିତ ଆଇଟମ୍ ବାତିଲ୍ କରନ୍ତୁ</translation> <translation id="7846621471902887024">ଆପଣ ସମସ୍ତ ସାଇଟରୁ ସାଇନ୍ ଆଉଟ୍ ହୋଇଯିବେ।</translation> <translation id="7882806643839505685">ଏକ ନିର୍ଦ୍ଧିଷ୍ଟ ସାଇଟ୍ରେ ଧ୍ୱନୀ ପାଇଁ ଅନୁମତି ଦିଅନ୍ତୁ।</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">ଆପଣ କ’ଣ ସୁନିଶ୍ଚିତ ଯେ ଆପଣ କୁକୀ ସହିତ ଏହି ୱେବ୍ସାଇଟ୍ର ସମସ୍ତ ସ୍ଥାନୀୟ ଡାଟା ଖାଲି କରିବା ଏବଂ ଏହାର ସମସ୍ତ ଅନୁମତି ରିସେଟ୍ କରିବା ପାଇଁ ଚାହୁଁଛନ୍ତି?</translation> <translation id="8007176423574883786">ଏହି ଡିଭାଇସ୍ ପାଇଁ ବନ୍ଦ କରନ୍ତୁ</translation> <translation id="802154636333426148">ଡାଉନ୍ଲୋଡ୍ ବିଫଳ ହୋଇଛି</translation> +<translation id="8068648041423924542">ସାର୍ଟିଫିକେଟ୍ ଚୟନ କରିବାକୁ ଅକ୍ଷମ।</translation> <translation id="8087000398470557479">ଏହି ବିଷୟବସ୍ତୁ Google ଦ୍ଵାରା ବିତରଣ କରାଯାଇଥିବା <ph name="DOMAIN_NAME" />ରୁ ଆସିଛି।</translation> <translation id="8116925261070264013">ମ୍ୟୁଟ୍ କରାଗଲା</translation> <translation id="8131740175452115882">ନିଶ୍ଚିତ କରନ୍ତୁ</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">କୌଣସି ସାଇଟ୍ ଆପଣଙ୍କ କ୍ୟାମେରା ଏବଂ ମାଇକ୍ରୋଫୋନକୁ ବ୍ୟବହାର କରୁଛି</translation> <translation id="8380167699614421159">ଏହି ସାଇଟ୍, ଅନଧିକାର ପ୍ରବେଶ କରିଥିବା କିମ୍ବା ବିଭ୍ରାନ୍ତିକର ବିଜ୍ଞାପନ ଦେଖାଉଛି</translation> <translation id="8394832520002899662">ସାଇଟକୁ ଫେରିବାକୁ ଟାପ୍ କରନ୍ତୁ</translation> +<translation id="8425213833346101688">ପରିବର୍ତ୍ତନ କରନ୍ତୁ</translation> +<translation id="8441146129660941386">ପଛକୁ ଫେରନ୍ତୁ</translation> <translation id="8447861592752582886">ଡିଭାଇସ୍ ଅନୁମତି କାଢ଼ି ଦିଅନ୍ତୁ</translation> <translation id="8463851957836045671">ସାଇଟ୍ ଶୀଘ୍ର ଲୋଡ୍ ହୁଏ</translation> <translation id="851751545965956758">ସାଇଟ୍ଗୁଡ଼ିକୁ ଡିଭାଇସ୍ଗୁଡ଼ିକ ସହିତ ସଂଯୋଗ ହେବାରୁ ବ୍ଲକ୍ କରନ୍ତୁ</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">ଏକ ନିର୍ଦ୍ଦିଷ୍ଟ ସାଇଟ୍ ପାଇଁ କୁକୀଗୁଡ଼ିକୁ ଅବରୋଧ କରନ୍ତୁ।</translation> <translation id="8959122750345127698">ନାଭିଗେସନ୍ରେ ପହଞ୍ଚି ହେଉନାହିଁ: <ph name="URL" /></translation> <translation id="9019902583201351841">ଆପଣଙ୍କ ମାତା-ପିତାଙ୍କ ଦ୍ୱାରା ପରିଚାଳିତ କରାଯାଉଛି</translation> +<translation id="9074739597929991885">ବ୍ଲୁଟୁଥ୍</translation> <translation id="945632385593298557">ଆପଣଙ୍କର ମାଇକ୍ରୋଫୋନ୍ ଆକ୍ସେସ୍ କରନ୍ତୁ</translation> <translation id="965817943346481315">ଯଦି ସାଇଟ୍ ଅନଧିକାର ପ୍ରବେଶ କରିଥିବା କିମ୍ବା ବିଭ୍ରାନ୍ତିକର ବିଜ୍ଞାପନ ଦେଖାଉଛି, ତେବେ ବ୍ଲକ୍ କରନ୍ତୁ(ସୁପାରିଶ୍ କରାଯାଇଛି)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_pa.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_pa.xtb index 13557e0bf1c..3b94551f7f4 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_pa.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_pa.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">ਅੱਗੇ</translation> <translation id="1242008676835033345"><ph name="WEBSITE_URL" /> 'ਤੇ ਪਰੋਇਆ ਗਿਆ</translation> <translation id="1272079795634619415">ਰੋਕੋ</translation> +<translation id="1289742167380433257">ਤੁਹਾਡਾ ਡਾਟਾ ਰੱਖਿਅਤ ਕਰਨ ਲਈ, Google ਨੇ ਇਸ ਪੰਨੇ ਦੇ ਚਿੱਤਰਾਂ ਨੂੰ ਸੁਯੋਗ ਬਣਾਇਆ ਹੈ।</translation> <translation id="129382876167171263">ਵੈੱਬਸਾਈਟਾਂ ਵੱਲੋਂ ਰੱਖਿਅਤ ਕੀਤੀਆਂ ਫ਼ਾਈਲਾਂ ਇੱਥੇ ਦਿਸਣਗੀਆਂ</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> - <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">ਸਾਈਟ <ph name="SITE_NAME" /> ਜੋੜੀ ਗਈ</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">ਸਾਈਟਾਂ ਵੱਲੋਂ ਤੁਹਾਡੇ ਆਲੇ-ਦੁਆਲੇ ਦਾ 3D ਨਕਸ਼ਾ ਬਣਾਉਣ ਜਾਂ ਕੈਮਰਾ ਸਥਿਤੀ ਨੂੰ ਟਰੈਕ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਦੇਣ ਤੋਂ ਪਹਿਲਾਂ ਪੁੱਛੋ (ਸਿਫ਼ਾਰਸ਼ੀ)</translation> <translation id="2212565012507486665">ਕੁਕੀਜ਼ ਨੂੰ ਆਗਿਆ ਦਿਓ</translation> <translation id="2289270750774289114">ਕਿਸੇ ਸਾਈਟ ਵੱਲੋਂ ਨਜ਼ਦੀਕੀ ਬਲੂਟੁੱਥ ਡੀਵਾਈਸਾਂ ਦਾ ਪਤਾ ਲਗਾਉਣ ਵੇਲੇ ਪੁੱਛੋ (ਸਿਫ਼ਾਰਸ਼ੀ)</translation> +<translation id="2315043854645842844">ਕਲਾਈਂਟ ਵੱਲੋਂ ਕੀਤੀ ਗਈ ਪ੍ਰਮਾਣ-ਪੱਤਰ ਦੀ ਚੋਣ ਓਪਰੇਟਿੰਗ ਸਿਸਟਮ ਵੱਲੋਂ ਸਮਰਥਿਤ ਨਹੀਂ ਹੈ।</translation> <translation id="2359808026110333948">ਜਾਰੀ ਰੱਖੋ</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">ਡਾਊਨਲੋਡ ਮੁਕੰਮਲ ਹੋਇਆ <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">ਕਾਪੀ ਕੀਤਾ</translation> <translation id="2822354292072154809">ਕੀ ਤੁਸੀਂ ਪੱਕਾ <ph name="CHOSEN_OBJECT_NAME" /> ਲਈ ਸਾਰੀਆਂ ਸਾਈਟ ਇਜਾਜ਼ਤਾਂ ਨੂੰ ਰੀਸੈੱਟ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?</translation> <translation id="2870560284913253234">ਸਾਈਟ</translation> +<translation id="2874939134665556319">ਪਿਛਲਾ ਟਰੈਕ</translation> <translation id="2910701580606108292">ਸਾਈਟਾਂ ਨੂੰ ਸੁਰੱਖਿਅਤ ਸਮੱਗਰੀ ਚਲਾਉਣ ਦੇਣ ਤੋਂ ਪਹਿਲਾਂ ਪੁੱਛੋ</translation> <translation id="2913331724188855103">ਸਾਈਟਾਂ ਨੂੰ ਕੁਕੀ ਡਾਟਾ ਰੱਖਿਅਤ ਕਰਨ ਅਤੇ ਪੜ੍ਹਨ ਦੀ ਇਜਾਜ਼ਤ ਦਿਓ (ਸਿਫ਼ਾਰਸ਼ੀ)</translation> <translation id="2968755619301702150">ਪ੍ਰਮਾਣ-ਪੱਤਰ ਵਿਊਅਰ</translation> <translation id="300526633675317032">ਇਸ ਨਾਲ ਵੈੱਬਸਾਈਟ ਸਟੋਰੇਜ ਦਾ ਸਾਰਾ <ph name="SIZE_IN_KB" /> ਡਾਟਾ ਕਲੀਅਰ ਹੋ ਜਾਵੇਗਾ।</translation> +<translation id="301521992641321250">ਸਵੈਚਲਿਤ ਤੌਰ 'ਤੇ ਬਲੌਕ ਕੀਤੀ ਗਈ</translation> <translation id="3115898365077584848">ਜਾਣਕਾਰੀ ਦਿਖਾਓ</translation> <translation id="3123473560110926937">ਕੁਝ ਸਾਈਟਾਂ 'ਤੇ ਬਲਾਕ ਕੀਤੇ ਗਏ</translation> <translation id="3190152372525844641">Chrome ਲਈ <ph name="BEGIN_LINK" />Android ਸੈਟਿੰਗਾਂ<ph name="END_LINK" /> ਵਿੱਚ ਇਜਾਜ਼ਤਾਂ ਚਾਲੂ ਕਰੋ।</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">ਬੈਕਗ੍ਰਾਊਂਡ ਸਮਕਾਲੀਕਰਨ</translation> <translation id="3822502789641063741">ਕੀ ਸਾਈਟ ਸਟੋਰੇਜ ਸਾਫ਼ ਕਰਨੀ ਹੈ?</translation> <translation id="385051799172605136">ਪਿੱਛੇ</translation> +<translation id="3859306556332390985">ਅੱਗੇ ਵੱਲ ਨੂੰ ਲੈ ਜਾਓ</translation> <translation id="3955193568934677022">ਸਾਈਟਾਂ ਨੂੰ ਸੁਰੱਖਿਅਤ ਸਮੱਗਰੀ ਚਲਾਉਣ ਦਿਓ (ਸਿਫ਼ਾਰਸ਼ੀ)</translation> <translation id="3987993985790029246">ਲਿੰਕ ਕਾਪੀ ਕਰੋ</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">ਸਿਰਲੇਖ</translation> <translation id="4008040567710660924">ਕਿਸੇ ਖਾਸ ਸਾਈਟ ਨੂੰ ਕੁਕੀਜ਼ ਨੂੰ ਵਰਤਣ ਦਿਓ।</translation> +<translation id="4046123991198612571">ਅਗਲਾ ਟਰੈਕ</translation> <translation id="4165986682804962316">ਸਾਈਟ ਸੈਟਿੰਗਾਂ</translation> <translation id="4226663524361240545">ਸੂਚਨਾਵਾਂ ਡੀਵਾਈਸ ਨੂੰ ਥਰਥਰਾਹਟ ਕਰ ਸਕਦੀਆਂ ਹਨ</translation> <translation id="4242533952199664413">ਸੈਟਿੰਗਾਂ ਖੋਲ੍ਹੋ</translation> <translation id="4259722352634471385">ਨੈਵੀਗੇਸ਼ਨ ਬਲੌਕ ਕੀਤੀ ਹੈ: <ph name="URL" /></translation> <translation id="4278390842282768270">ਆਗਿਆ ਦਿੱਤੀ</translation> +<translation id="429312253194641664">ਕੋਈ ਸਾਈਟ ਮੀਡੀਆ ਫ਼ਾਈਲ ਨੂੰ ਚਲਾ ਰਹੀ ਹੈ</translation> <translation id="4433925000917964731">Google ਵੱਲੋਂ ਮੁਹੱਈਆ ਕਰਵਾਏ ਗਏ ਤੇਜ਼ੀ ਨਾਲ ਖੁੱਲ੍ਹਣ ਵਾਲੇ ਪੰਨੇ</translation> <translation id="4434045419905280838">ਪੌਪ-ਅੱਪ ਅਤੇ ਰੀਡਾਇਰੈਕਟ</translation> <translation id="445467742685312942">ਸਾਈਟਾਂ ਨੂੰ ਸੁਰੱਖਿਅਤ ਕੀਤੀ ਸਮੱਗਰੀ ਚਲਾਉਣ ਦਿਓ</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">ਡੀਵਾਈਸ ਲਈ ਸਾਰੀਆਂ ਇਜਾਜ਼ਤਾਂ ਨੂੰ ਰੱਦ ਕਰੋ</translation> <translation id="4964199952259983386">Chrome ਨੂੰ AR ਵਰਤਣ ਦੇਣ ਲਈ <ph name="BEGIN_LINK" />Android ਸੈਟਿੰਗਾਂ<ph name="END_LINK" /> ਵਿੱਚ ਕੈਮਰਾ ਵੀ ਚਾਲੂ ਕਰੋ।</translation> <translation id="497421865427891073">ਅੱਗੇ ਵੱਲ ਜਾਓ</translation> +<translation id="4996978546172906250">ਰਾਹੀਂ ਸ਼ੇਅਰ ਕਰੋ</translation> <translation id="5039804452771397117">ਆਗਿਆ ਦਿਓ</translation> <translation id="5048398596102334565">ਸਾਈਟਾਂ ਨੂੰ ਗਤੀਸ਼ੀਲਤਾ ਸੈਂਸਰਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦਿਓ (ਸਿਫ਼ਾਰਸ਼ੀ)</translation> <translation id="5063480226653192405">ਵਰਤੋਂ</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">ਹਟਾਓ</translation> <translation id="6697925417670533197">ਕਿਰਿਆਸ਼ੀਲ ਡਾਊਨਲੋਡ</translation> <translation id="6746124502594467657">ਹੇਠਾਂ ਜਾਓ</translation> +<translation id="6766622839693428701">ਬੰਦ ਕਰਨ ਲਈ ਹੇਠਾਂ ਵੱਲ ਸਵਾਈਪ ਕਰੋ।</translation> <translation id="6782111308708962316">ਤੀਜੀ-ਧਿਰ ਵਾਲੀਆਂ ਵੈੱਬਸਾਈਟਾਂ ਨੂੰ ਕੁਕੀ ਡਾਟੇ ਨੂੰ ਰੱਖਿਅਤ ਕਰਨ ਅਤੇ ਪੜ੍ਹਨ ਤੋਂ ਰੋਕੋ</translation> +<translation id="6790428901817661496">ਪਲੇ ਕਰੋ</translation> <translation id="6818926723028410516">ਆਈਟਮਾਂ ਚੁਣੋ</translation> <translation id="6864395892908308021">ਇਹ ਡੀਵਾਈਸ NFC ਨੂੰ ਨਹੀਂ ਪੜ੍ਹ ਸਕਦਾ</translation> <translation id="6910211073230771657">ਮਿਟਾਇਆ ਗਿਆ</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">ਕੋਈ ਸਾਈਟ ਤੁਹਾਡਾ ਕੈਮਰਾ ਵਰਤ ਰਹੀ ਹੈ</translation> <translation id="7817023149356982970">ਤੁਹਾਨੂੰ ਇਸ ਸਾਈਟ ਤੋਂ ਸਾਈਨ-ਆਊਟ ਕਰ ਦਿੱਤਾ ਜਾਵੇਗਾ।</translation> <translation id="7828557259026017104">ਕੁਕੀਜ਼ ਉਹ ਫ਼ਾਈਲਾਂ ਹਨ ਜੋ ਤੁਹਾਡੇ ਵੱਲੋਂ ਦੇਖੀਆਂ ਵੈੱਬਸਾਈਟਾਂ ਦੁਆਰਾ ਬਣਾਈਆਂ ਜਾਂਦੀਆਂ ਹਨ। ਸਾਈਟਾਂ ਉਹਨਾਂ ਨੂੰ ਤੁਹਾਡੀਆਂ ਤਰਜੀਹਾਂ ਯਾਦ ਰੱਖਣ ਲਈ ਵਰਤਦੀਆਂ ਹਨ। ਤੀਜੀ-ਧਿਰ ਦੀਆਂ ਕੁਕੀਜ਼ ਹੋਰ ਸਾਈਟਾਂ ਵੱਲੋਂ ਬਣਾਈਆਂ ਜਾਂਦੀਆਂ ਹਨ। ਇਹ ਸਾਈਟਾਂ ਵਿਗਿਆਪਨਾਂ ਜਾਂ ਚਿੱਤਰਾਂ ਵਰਗੀ ਕੁਝ ਸਮੱਗਰੀ ਦੀਆਂ ਮਾਲਕ ਹੁੰਦੀਆਂ ਹਨ, ਜੋ ਤੁਸੀਂ ਵੈੱਬਸਾਈਟ 'ਤੇ ਦੇਖਦੇ ਹੋ।</translation> +<translation id="7835852323729233924">ਮੀਡੀਆ ਚਲਾਇਆ ਜਾ ਰਿਹਾ ਹੈ</translation> <translation id="7846076177841592234">ਚੋਣ ਰੱਦ ਕਰੋ</translation> <translation id="7846621471902887024">ਤੁਹਾਨੂੰ ਸਾਰੀਆਂ ਸਾਈਟਾਂ ਤੋਂ ਸਾਈਨ-ਆਊਟ ਕਰ ਦਿੱਤਾ ਜਾਵੇਗਾ।</translation> <translation id="7882806643839505685">ਕਿਸੇ ਖ਼ਾਸ ਸਾਈਟ ਲਈ ਧੁਨੀ ਵਜਾਉਣ ਦੀ ਆਗਿਆ ਦਿਓ।</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">ਕੀ ਤੁਸੀਂ ਪੱਕਾ ਕੁਕੀਜ਼ ਸਮੇਤ ਸਾਰਾ ਸਥਾਨਕ ਡਾਟਾ ਮਿਟਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ ਅਤੇ ਇਸ ਵੈੱਬਸਾਈਟ ਲਈ ਸਾਰੀਆਂ ਇਜਾਜ਼ਤਾਂ ਨੂੰ ਰੀਸੈੱਟ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?</translation> <translation id="8007176423574883786">ਇਸ ਡਿਵਾਈਸ ਲਈ ਬੰਦ ਕੀਤਾ ਗਿਆ</translation> <translation id="802154636333426148">ਡਾਊਨਲੋਡ ਅਸਫਲ ਰਿਹਾ</translation> +<translation id="8068648041423924542">ਪ੍ਰਮਾਣ-ਪੱਤਰ ਚੁਣਨ ਵਿੱਚ ਅਸਮਰੱਥ।</translation> <translation id="8087000398470557479">ਇਸ ਸਮੱਗਰੀ <ph name="DOMAIN_NAME" /> ਵੱਲੋਂ ਹੈ, ਜਿਸਨੂੰ Google ਡਿਲੀਵਰ ਕਰਦਾ ਹੈ।</translation> <translation id="8116925261070264013">ਮਿਊਟ ਕੀਤਾ ਗਿਆ</translation> <translation id="8131740175452115882">ਪੁਸ਼ਟੀ ਕਰੋ</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">ਕੋਈ ਸਾਈਟ ਤੁਹਾਡਾ ਕੈਮਰਾ ਅਤੇ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਵਰਤ ਰਹੀ ਹੈ</translation> <translation id="8380167699614421159">ਇਹ ਸਾਈਟ ਦਖਲਅੰਦਾਜ਼ੀ ਜਾਂ ਗੁਮਰਾਹ ਕਰਨ ਵਾਲੇ ਵਿਗਿਆਪਨ ਦਿਖਾਉਂਦੀ ਹੈ</translation> <translation id="8394832520002899662">ਸਾਈਟ 'ਤੇ ਵਾਪਸ ਜਾਣ ਲਈ ਟੈਪ ਕਰੋ</translation> +<translation id="8425213833346101688">ਬਦਲੋ</translation> +<translation id="8441146129660941386">ਪਿੱਛੇ ਵੱਲ ਨੂੰ ਲੈ ਜਾਓ</translation> <translation id="8447861592752582886">ਡੀਵਾਈਸ 'ਤੇ ਪਹੁੰਚ ਦੀ ਇਜਾਜ਼ਤ ਰੱਦ ਕਰੋ</translation> <translation id="8463851957836045671">ਸਾਈਟ ਤੇਜ਼ ਹੈ</translation> <translation id="851751545965956758">ਸਾਈਟਾਂ ਨੂੰ ਡੀਵਾਈਸਾਂ ਨਾਲ ਕਨੈਕਟ ਕਰਨ ਤੋਂ ਬਲਾਕ ਕਰੋ</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">ਕਿਸੇ ਖਾਸ ਸਾਈਟ ਲਈ ਕੁਕੀਜ਼ ਬਲਾਕ ਕਰੋ।</translation> <translation id="8959122750345127698">ਨੈਵੀਗੇਸ਼ਨ ਨਾਪਹੁੰਚਯੋਗ ਹੈ: <ph name="URL" /></translation> <translation id="9019902583201351841">ਤੁਹਾਡੇ ਮਾਪਿਆਂ ਵੱਲੋਂ ਵਿਵਸਥਿਤ</translation> +<translation id="9074739597929991885">ਬਲੂਟੁੱਥ</translation> <translation id="945632385593298557">ਆਪਣੇ ਮਾਈਕ੍ਰੋਫੋਨ ਤੱਕ ਪਹੁੰਚੋ</translation> <translation id="965817943346481315">ਜੇਕਰ ਸਾਈਟ ਦਖਲਅੰਦਾਜ਼ੀ ਅਤੇ ਗੁਮਰਾਹ ਕਰਨ ਵਾਲੇ ਵਿਗਿਆਪਨ ਦਿਖਾਉਂਦੀ ਹੈ, ਤਾਂ ਇਸਨੂੰ ਬਲਾਕ ਕਰੋ (ਸਿਫ਼ਾਰਸ਼ੀ)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_pl.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_pl.xtb index dbc0c87b911..9668cbb1f84 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_pl.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_pl.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Dalej</translation> <translation id="1242008676835033345">Umieszczono na <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Zatrzymaj</translation> +<translation id="1289742167380433257">Aby zaoszczędzić dane, obrazy z tej strony zostały zoptymalizowane przez Google.</translation> <translation id="129382876167171263">W tym miejscu pojawiają się pliki zapisane przez witryny</translation> <translation id="1364532808393826295"><ph name="APP_NAME" />–<ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Strona <ph name="SITE_NAME" /> została dodana</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Pytaj, zanim zezwolisz stronom na tworzenie mapy 3D Twojego otoczenia lub śledzenie pozycji kamery (zalecane)</translation> <translation id="2212565012507486665">Zezwalaj na pliki cookie</translation> <translation id="2289270750774289114">Pytaj, gdy strona chce wykryć urządzenia Bluetooth w pobliżu (zalecane)</translation> +<translation id="2315043854645842844">Wybieranie certyfikatu klienta nie jest obsługiwane przez ten system operacyjny.</translation> <translation id="2359808026110333948">Dalej</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">Ukończono pobieranie <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Skopiowane</translation> <translation id="2822354292072154809">Czy na pewno chcesz zresetować wszystkie uprawnienia witryny dla obiektu <ph name="CHOSEN_OBJECT_NAME" />?</translation> <translation id="2870560284913253234">Witryna</translation> +<translation id="2874939134665556319">Poprzedni utwór</translation> <translation id="2910701580606108292">Pytaj, zanim zezwolisz stronom na odtwarzanie treści chronionej</translation> <translation id="2913331724188855103">Zezwalaj witrynom na zapisywanie danych w plikach cookie i ich odczytywanie (zalecane)</translation> <translation id="2968755619301702150">Przeglądarka certyfikatów</translation> <translation id="300526633675317032">Spowoduje to usunięcie <ph name="SIZE_IN_KB" /> danych witryn.</translation> +<translation id="301521992641321250">Automatycznie zablokowane</translation> <translation id="3115898365077584848">Pokaż informacje</translation> <translation id="3123473560110926937">Blokowane na niektórych stronach</translation> <translation id="3190152372525844641">Przyznaj Chrome uprawnienia w <ph name="BEGIN_LINK" />ustawieniach Androida<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Synchronizacja w tle</translation> <translation id="3822502789641063741">Wyczyścić dane witryn?</translation> <translation id="385051799172605136">Wstecz</translation> +<translation id="3859306556332390985">Przewiń do przodu</translation> <translation id="3955193568934677022">Zezwalaj witrynom na odtwarzanie treści chronionej (zalecane)</translation> <translation id="3987993985790029246">Kopiuj link</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">Tytuł</translation> <translation id="4008040567710660924">Zezwalaj na pliki cookie z określonej strony internetowej.</translation> +<translation id="4046123991198612571">Następny utwór</translation> <translation id="4165986682804962316">Ustawienia witryn</translation> <translation id="4226663524361240545">Powiadomienia będą sygnalizowane wibracjami</translation> <translation id="4242533952199664413">Otwórz ustawienia</translation> <translation id="4259722352634471385">Adres zablokowany: <ph name="URL" /></translation> <translation id="4278390842282768270">Dopuszczone</translation> +<translation id="429312253194641664">Strona odtwarza multimedia</translation> <translation id="4433925000917964731">Lżejsza wersja strony dostarczona przez Google</translation> <translation id="4434045419905280838">Pop-upy i przekierowania</translation> <translation id="445467742685312942">Zezwalaj stronom na odtwarzanie treści chronionych</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Anuluj wszystkie uprawnienia urządzenia</translation> <translation id="4964199952259983386">Aby w Chrome można było korzystać z AR, włącz też kamerę w <ph name="BEGIN_LINK" />ustawieniach Androida<ph name="END_LINK" />.</translation> <translation id="497421865427891073">Dalej</translation> +<translation id="4996978546172906250">Udostępnij przez</translation> <translation id="5039804452771397117">Zezwalaj</translation> <translation id="5048398596102334565">Zezwalaj stronom na dostęp do czujników ruchu (zalecane)</translation> <translation id="5063480226653192405">Wykorzystanie</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Wyczyść</translation> <translation id="6697925417670533197">W trakcie pobierania</translation> <translation id="6746124502594467657">W dół</translation> +<translation id="6766622839693428701">Przesuń w dół, by zamknąć.</translation> <translation id="6782111308708962316">Nie pozwalaj witrynom innych firm zapisywać ani odczytywać danych z plików cookie</translation> +<translation id="6790428901817661496">Odtwórz</translation> <translation id="6818926723028410516">Wybierz elementy</translation> <translation id="6864395892908308021">To urządzenie nie obsługuje NFC</translation> <translation id="6910211073230771657">Usunięto</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Strona używa kamery</translation> <translation id="7817023149356982970">Wylogujemy Cię z tej strony.</translation> <translation id="7828557259026017104">Pliki cookie są tworzone przez odwiedzane witryny. Witryny zapisują w nich Twoje ustawienia. Pliki cookie innych firm są tworzone przez inne witryny. W tych witrynach znajdują się niektóre treści, np. reklamy i obrazy, które wyświetlają się na odwiedzanej stronie.</translation> +<translation id="7835852323729233924">Odtwarzanie multimediów</translation> <translation id="7846076177841592234">Anuluj wybór</translation> <translation id="7846621471902887024">Wylogujemy Cię ze wszystkich stron.</translation> <translation id="7882806643839505685">Zezwalaj na dźwięk na określonej stronie.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Na pewno chcesz usunąć wszystkie dane lokalne (w tym pliki cookie) i zresetować uprawnienia tej witryny?</translation> <translation id="8007176423574883786">Wyłączona na tym urządzeniu</translation> <translation id="802154636333426148">Nie udało się pobrać</translation> +<translation id="8068648041423924542">Nie można wybrać certyfikatu.</translation> <translation id="8087000398470557479">Treść z <ph name="DOMAIN_NAME" /> dostarczana przez Google.</translation> <translation id="8116925261070264013">Wyciszone</translation> <translation id="8131740175452115882">Potwierdź</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Strona używa kamery i mikrofonu</translation> <translation id="8380167699614421159">Na tej stronie wyświetlają się uciążliwe lub wprowadzające w błąd reklamy</translation> <translation id="8394832520002899662">Kliknij, by wrócić na tę stronę</translation> +<translation id="8425213833346101688">Zmień</translation> +<translation id="8441146129660941386">Przewiń do tyłu</translation> <translation id="8447861592752582886">Cofnij zgodę na dostęp do urządzenia</translation> <translation id="8463851957836045671">Strona jest szybka</translation> <translation id="851751545965956758">Nie zezwalaj stronom na łączenie się z urządzeniami</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Blokuj pliki cookie z określonej strony internetowej.</translation> <translation id="8959122750345127698">Adres nieosiągalny: <ph name="URL" /></translation> <translation id="9019902583201351841">Zarządzany przez Twoich rodziców</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Dostęp do mikrofonu</translation> <translation id="965817943346481315">Zablokuj, jeśli na stronie wyświetlają się uciążliwe lub wprowadzające w błąd reklamy (zalecane)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_pt-BR.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_pt-BR.xtb index f0b57a98669..db38c113d5a 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_pt-BR.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_pt-BR.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Próxima</translation> <translation id="1242008676835033345">Incorporado em <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Parar</translation> +<translation id="1289742167380433257">Para que você economize dados, as imagens desta página foram otimizadas pelo Google.</translation> <translation id="129382876167171263">Os arquivos salvos por sites são exibidos aqui</translation> <translation id="1364532808393826295"><ph name="APP_NAME" />: <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Site <ph name="SITE_NAME" /> adicionado</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Perguntar antes de permitir que sites criem um mapa 3D dos seus arredores ou acompanhem a posição da câmera (recomendado)</translation> <translation id="2212565012507486665">Permitir cookies</translation> <translation id="2289270750774289114">Perguntar quando um site quer descobrir dispositivos Bluetooth nas proximidades (recomendado)</translation> +<translation id="2315043854645842844">A seleção de certificado do cliente não é compatível com o sistema operacional.</translation> <translation id="2359808026110333948">Continuar</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">Download concluído <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Copiado</translation> <translation id="2822354292072154809">Tem certeza de que quer redefinir todas as permissões de site para <ph name="CHOSEN_OBJECT_NAME" />?</translation> <translation id="2870560284913253234">Site</translation> +<translation id="2874939134665556319">Faixa anterior</translation> <translation id="2910701580606108292">Perguntar antes de permitir que sites reproduzam conteúdo protegido</translation> <translation id="2913331724188855103">Permitir que os sites salvem e leiam os dados de arquivos "cookies" - que armazenam temporariamente o que você visitou na rede. (Recomendado)</translation> <translation id="2968755619301702150">Leitor de certificados</translation> <translation id="300526633675317032">Essa ação limpará tudo, <ph name="SIZE_IN_KB" /> de dados de armazenamento de sites.</translation> +<translation id="301521992641321250">Bloqueada automaticamente</translation> <translation id="3115898365077584848">Mostrar informações</translation> <translation id="3123473560110926937">Bloqueados em alguns sites</translation> <translation id="3190152372525844641">Ative as permissões para o Chrome nas <ph name="BEGIN_LINK" />configurações do Android<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Sincronização em segundo plano</translation> <translation id="3822502789641063741">Limpar armazenamento de sites?</translation> <translation id="385051799172605136">Voltar</translation> +<translation id="3859306556332390985">Avançar</translation> <translation id="3955193568934677022">Permitir que os sites reproduzam conteúdo protegido (recomendado)</translation> <translation id="3987993985790029246">Copiar link</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">Título</translation> <translation id="4008040567710660924">Permita cookies para um site específico.</translation> +<translation id="4046123991198612571">Próxima faixa</translation> <translation id="4165986682804962316">Configurações do site</translation> <translation id="4226663524361240545">É possível que as notificações façam o dispositivo vibrar</translation> <translation id="4242533952199664413">Abrir configurações.</translation> <translation id="4259722352634471385">A Navegação GPS está bloqueada: <ph name="URL" /></translation> <translation id="4278390842282768270">Permitido</translation> +<translation id="429312253194641664">Um site está com mídia aberta</translation> <translation id="4433925000917964731">Página Lite exibida pelo Google</translation> <translation id="4434045419905280838">Pop-ups e redirecionamentos</translation> <translation id="445467742685312942">Permitir que sites reproduzam conteúdo protegido</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Revogar todas as permissões para o dispositivo</translation> <translation id="4964199952259983386">Para permitir que o Chrome use RA, ative também a câmera em <ph name="BEGIN_LINK" />configurações do Android<ph name="END_LINK" />.</translation> <translation id="497421865427891073">Avançar</translation> +<translation id="4996978546172906250">Compartilhar via</translation> <translation id="5039804452771397117">Permitir</translation> <translation id="5048398596102334565">Permitir o acesso de sites aos seus sensores de movimento (recomendado)</translation> <translation id="5063480226653192405">Uso</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Limpar</translation> <translation id="6697925417670533197">Downloads ativos</translation> <translation id="6746124502594467657">Mover para baixo</translation> +<translation id="6766622839693428701">Deslize para baixo para fechar.</translation> <translation id="6782111308708962316">Impedir sites de terceiros de salvar e ler dados de cookies</translation> +<translation id="6790428901817661496">Reproduzir</translation> <translation id="6818926723028410516">Selecionar itens</translation> <translation id="6864395892908308021">O dispositivo não consegue ler a NFC</translation> <translation id="6910211073230771657">Excluído</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Um site está usando sua câmera</translation> <translation id="7817023149356982970">Sua conta será desconectada desse site.</translation> <translation id="7828557259026017104">Os cookies são arquivos criados pelos sites que você visita, usados por esses sites para lembrar suas preferências. Os cookies de terceiros são criados por outros sites que possuem uma parte do conteúdo, como anúncios ou imagens, que você vê na página da Web acessada.</translation> +<translation id="7835852323729233924">Tocando mídia</translation> <translation id="7846076177841592234">Cancelar seleção</translation> <translation id="7846621471902887024">Sua conta será desconectada de todos os sites.</translation> <translation id="7882806643839505685">Permitir o som de um site específico.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Você quer mesmo apagar todos os dados locais, inclusive os cookies, e redefinir todas as permissões para este website?</translation> <translation id="8007176423574883786">Desativado neste dispositivo</translation> <translation id="802154636333426148">Falha no download</translation> +<translation id="8068648041423924542">Não foi possível selecionar certificado.</translation> <translation id="8087000398470557479">Este conteúdo é de <ph name="DOMAIN_NAME" />, veiculado pelo Google.</translation> <translation id="8116925261070264013">Com som desativado</translation> <translation id="8131740175452115882">Confirmar</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Um site está usando sua câmera e seu microfone</translation> <translation id="8380167699614421159">Neste site, há exibição de anúncios invasivos ou enganosos</translation> <translation id="8394832520002899662">Toque para voltar ao site</translation> +<translation id="8425213833346101688">Alterar</translation> +<translation id="8441146129660941386">Retroceder</translation> <translation id="8447861592752582886">Revogar permissão do dispositivo</translation> <translation id="8463851957836045671">O site é rápido</translation> <translation id="851751545965956758">Impedir a conexão de sites a dispositivos</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Bloqueie cookies de um site específico.</translation> <translation id="8959122750345127698">A Navegação GPS está inacessível: <ph name="URL" /></translation> <translation id="9019902583201351841">Gerenciado pelos seus pais</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Acessar seu microfone</translation> <translation id="965817943346481315">Bloquear se o site mostrar anúncios invasivos ou enganosos (recomendado)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_pt-PT.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_pt-PT.xtb index 10bb2eadcdf..703c0c7c8a7 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_pt-PT.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_pt-PT.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Seguinte</translation> <translation id="1242008676835033345">Incorporada em <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Parar</translation> +<translation id="1289742167380433257">Para guardar os seus dados, as imagens desta página foram otimizadas pela Google.</translation> <translation id="129382876167171263">Os ficheiros guardados por Websites são apresentados aqui.</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> – <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Site <ph name="SITE_NAME" /> adicionado</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Perguntar antes de permitir que os sites criem um mapa 3D do ambiente à sua volta ou monitorizem a posição da câmara (recomendado)</translation> <translation id="2212565012507486665">Permitir cookies</translation> <translation id="2289270750774289114">Perguntar quando um site pretende detetar dispositivos Bluetooth próximos (recomendado)</translation> +<translation id="2315043854645842844">O sistema operativo não suporta a seleção do certificado do lado do cliente.</translation> <translation id="2359808026110333948">Continuar</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">Transferência concluída: <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Copiado</translation> <translation id="2822354292072154809">Tem a certeza de que pretende repor todas as autorizações do site para <ph name="CHOSEN_OBJECT_NAME" />?</translation> <translation id="2870560284913253234">Site</translation> +<translation id="2874939134665556319">Faixa anterior</translation> <translation id="2910701580606108292">Perguntar antes de permitir que os sites reproduzam conteúdos protegidos</translation> <translation id="2913331724188855103">Permitir que os sites guardem e leiam dados de cookies (recomendado)</translation> <translation id="2968755619301702150">Visualizador de certificados</translation> <translation id="300526633675317032">Esta ação elimina os <ph name="SIZE_IN_KB" /> de armazenamento do Website.</translation> +<translation id="301521992641321250">Bloqueada automaticamente</translation> <translation id="3115898365077584848">Mostrar informações</translation> <translation id="3123473560110926937">Bloqueado em alguns sites.</translation> <translation id="3190152372525844641">Ative as autorizações para o Chrome nas <ph name="BEGIN_LINK" />Definições do Android<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Sincronização em segundo plano</translation> <translation id="3822502789641063741">Limpar armazenamento do site?</translation> <translation id="385051799172605136">Anterior</translation> +<translation id="3859306556332390985">Procurar para a frente</translation> <translation id="3955193568934677022">Permitir que os sites reproduzam conteúdo protegido (recomendado)</translation> <translation id="3987993985790029246">Cop. link</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> <translation id="4002066346123236978">Título</translation> <translation id="4008040567710660924">Permita cookies para um site específico.</translation> +<translation id="4046123991198612571">Faixa seguinte</translation> <translation id="4165986682804962316">Definições de sites</translation> <translation id="4226663524361240545">As notificações podem fazer com que o dispositivo vibre</translation> <translation id="4242533952199664413">Abrir definições</translation> <translation id="4259722352634471385">A navegação está bloqueada: <ph name="URL" /></translation> <translation id="4278390842282768270">Permitido</translation> +<translation id="429312253194641664">Um site está a reproduzir multimédia.</translation> <translation id="4433925000917964731">Página em modo lite fornecida pela Google</translation> <translation id="4434045419905280838">Pop-ups e redirecionamentos</translation> <translation id="445467742685312942">Permitir que os sites reproduzam conteúdos protegidos</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Revogar todas as autorizações do dispositivo</translation> <translation id="4964199952259983386">Para permitir que o Chrome utilize a realidade aumentada, ative também a câmara nas <ph name="BEGIN_LINK" />Definições do Android<ph name="END_LINK" />.</translation> <translation id="497421865427891073">Avançar</translation> +<translation id="4996978546172906250">Partilhar através de</translation> <translation id="5039804452771397117">Permitir</translation> <translation id="5048398596102334565">Permitir que os sites acedam aos sensores de movimentos (recomendado)</translation> <translation id="5063480226653192405">Utilização</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Limpar</translation> <translation id="6697925417670533197">Transferências ativas</translation> <translation id="6746124502594467657">Mover para baixo</translation> +<translation id="6766622839693428701">Deslize rapidamente para baixo para fechar.</translation> <translation id="6782111308708962316">Impedir que os Sites de terceiros guardem e leiam dados de cookies</translation> +<translation id="6790428901817661496">Reproduzir</translation> <translation id="6818926723028410516">Selecionar itens</translation> <translation id="6864395892908308021">Este dispositivo não suporta a tecnologia NFC.</translation> <translation id="6910211073230771657">Eliminado</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Um site está a utilizar a sua câmara.</translation> <translation id="7817023149356982970">A sua sessão será terminada neste site.</translation> <translation id="7828557259026017104">Os cookies são ficheiros criados pelos Websites que visitou. Os sites utilizam os cookies para memorizar as suas preferências. Os cookies de terceiros são criados por outros sites. Estes sites possuem algum do conteúdo, tal como anúncios ou imagens, que vê na página Web que visita.</translation> +<translation id="7835852323729233924">Multimédia em reprodução</translation> <translation id="7846076177841592234">Cancelar seleção</translation> <translation id="7846621471902887024">A sua sessão terminará em todos os sites.</translation> <translation id="7882806643839505685">Permita a reprodução de som de um site específico.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Tem a certeza de que pretende limpar todos os dados locais, incluindo cookies, e repor todas as autorizações para este Website?</translation> <translation id="8007176423574883786">Desativada para este dispositivo</translation> <translation id="802154636333426148">Falha ao transferir</translation> +<translation id="8068648041423924542">Não é possível selecionar o certificado.</translation> <translation id="8087000398470557479">Este conteúdo é proveniente de <ph name="DOMAIN_NAME" />, fornecido pela Google.</translation> <translation id="8116925261070264013">Com som desativado</translation> <translation id="8131740175452115882">Confirmar</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Um site está a utilizar a sua câmara e microfone.</translation> <translation id="8380167699614421159">Este site apresenta anúncios intrusivos ou enganadores.</translation> <translation id="8394832520002899662">Toque para regressar ao site.</translation> +<translation id="8425213833346101688">Alterar</translation> +<translation id="8441146129660941386">Procurar para trás</translation> <translation id="8447861592752582886">Revogar autorização do dispositivo</translation> <translation id="8463851957836045671">O site é rápido</translation> <translation id="851751545965956758">Impedir a ligação de sites a dispositivos</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Bloqueie cookies para um site específico.</translation> <translation id="8959122750345127698">A navegação está inacessível: <ph name="URL" /></translation> <translation id="9019902583201351841">Gerido pelos teus pais</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Aceder ao microfone</translation> <translation id="965817943346481315">Bloquear se o site apresentar anúncios intrusivos ou enganadores (recomendado)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ro.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ro.xtb index 446d5deec4c..a31bf2c924f 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ro.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ro.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Înainte</translation> <translation id="1242008676835033345">Încorporat în <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Oprește</translation> +<translation id="1289742167380433257">Pentru a-ți salva datele, Google a optimizat imaginile din această pagină.</translation> <translation id="129382876167171263">Fișierele salvate de site-uri apar aici</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> – <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Site-ul <ph name="SITE_NAME" /> a fost adăugat</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Întreabă înainte de a permite site-urilor să creeze o hartă 3D a lucrurilor din jur sau să urmărească poziția camerei video (recomandat)</translation> <translation id="2212565012507486665">Permite cookie-urile</translation> <translation id="2289270750774289114">Întreabă-mă când un site dorește să descopere dispozitive Bluetooth din apropiere (recomandat)</translation> +<translation id="2315043854645842844">Selectarea certificatelor pe partea de client nu este acceptată de sistemul de operare.</translation> <translation id="2359808026110333948">Continuă</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">Descărcare finalizată <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Copiat</translation> <translation id="2822354292072154809">Sigur dorești să resetezi toate permisiunile la nivel de site pentru <ph name="CHOSEN_OBJECT_NAME" />?</translation> <translation id="2870560284913253234">Site</translation> +<translation id="2874939134665556319">Melodia anterioară</translation> <translation id="2910701580606108292">Întreabă înainte de a permite site-urilor să redea conținut protejat</translation> <translation id="2913331724188855103">Permite site-urilor să salveze și să citească datele asociate cookie-urilor (recomandat)</translation> <translation id="2968755619301702150">Vizualizator de certificate</translation> <translation id="300526633675317032">Astfel, se vor șterge <ph name="SIZE_IN_KB" /> din stocarea site-urilor.</translation> +<translation id="301521992641321250">Blocată automat</translation> <translation id="3115898365077584848">Afișează informațiile</translation> <translation id="3123473560110926937">Blocate pe anumite site-uri</translation> <translation id="3190152372525844641">Activează permisiunile pentru Chrome din <ph name="BEGIN_LINK" />Setări Android<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Sincronizare în fundal</translation> <translation id="3822502789641063741">Ștergi stocarea site-urilor?</translation> <translation id="385051799172605136">Înapoi</translation> +<translation id="3859306556332390985">Derulează înainte</translation> <translation id="3955193568934677022">Permite site-urilor să redea conținutul protejat (recomandat)</translation> <translation id="3987993985790029246">Copiază linkul</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">Titlu</translation> <translation id="4008040567710660924">Permite cookie-uri pentru un anumit site.</translation> +<translation id="4046123991198612571">Melodia următoare</translation> <translation id="4165986682804962316">Setări pentru site-uri</translation> <translation id="4226663524361240545">Notificările pot face dispozitivul să vibreze</translation> <translation id="4242533952199664413">Deschide setările</translation> <translation id="4259722352634471385">Navigarea este blocată: <ph name="URL" /></translation> <translation id="4278390842282768270">Se permite</translation> +<translation id="429312253194641664">Un site redă fișiere media</translation> <translation id="4433925000917964731">Pagină Lite oferită de Google</translation> <translation id="4434045419905280838">Ferestre pop-up și redirecționări</translation> <translation id="445467742685312942">Permite site-urilor să redea conținut protejat</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Revocă toate permisiunile pentru dispozitiv</translation> <translation id="4964199952259983386">Pentru a permite ca Chrome să folosească RA, activează camera foto în <ph name="BEGIN_LINK" />Setările Android<ph name="END_LINK" />.</translation> <translation id="497421865427891073">Înainte</translation> +<translation id="4996978546172906250">Trimite prin</translation> <translation id="5039804452771397117">Permite</translation> <translation id="5048398596102334565">Permite accesul site-urilor la senzorii de mișcare (recomandat)</translation> <translation id="5063480226653192405">Utilizare</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Șterge</translation> <translation id="6697925417670533197">Descărcări active</translation> <translation id="6746124502594467657">Mutați în jos</translation> +<translation id="6766622839693428701">Glisează în jos pentru a închide.</translation> <translation id="6782111308708962316">Împiedică site-urile terță parte să salveze și să citească datele asociate cookie-urilor</translation> +<translation id="6790428901817661496">Redă</translation> <translation id="6818926723028410516">Selectează elementele</translation> <translation id="6864395892908308021">Dispozitivul nu poate citi comunicările NFC</translation> <translation id="6910211073230771657">Șters</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Un site folosește camera foto</translation> <translation id="7817023149356982970">Te vei deconecta de la acest site.</translation> <translation id="7828557259026017104">Cookie-urile sunt fișiere create de site-urile pe care le accesezi. Site-urile le folosesc pentru a-ți reține preferințele. Cookie-urile terță parte sunt create de alte site-uri. Aceste site-uri dețin o parte din conținut, cum ar fi anunțuri sau imagini, pe care le vezi pe pagina web pe care o accesezi.</translation> +<translation id="7835852323729233924">Se redă conținutul media</translation> <translation id="7846076177841592234">Anulează selecția</translation> <translation id="7846621471902887024">Te vei deconecta de la toate site-urile.</translation> <translation id="7882806643839505685">Permite sunetul pentru un anumit site.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Sigur dorești să ștergi toate datele locale, inclusiv cookie-urile pentru acest site și să îi resetezi permisiunile?</translation> <translation id="8007176423574883786">Dezactivată pentru acest dispozitiv</translation> <translation id="802154636333426148">Descărcarea nu a reușit</translation> +<translation id="8068648041423924542">Certificatul nu poate fi selectat.</translation> <translation id="8087000398470557479">Acest conținut provine de pe <ph name="DOMAIN_NAME" />, oferit de Google.</translation> <translation id="8116925261070264013">Cu sunetul dezactivat</translation> <translation id="8131740175452115882">Confirmați</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Un site folosește camera foto și microfonul</translation> <translation id="8380167699614421159">Acest site afișează anunțuri deranjante sau înșelătoare</translation> <translation id="8394832520002899662">Atinge pentru a reveni la site</translation> +<translation id="8425213833346101688">Modificați</translation> +<translation id="8441146129660941386">Derulează înapoi</translation> <translation id="8447861592752582886">Revocă permisiunea de accesare a dispozitivului</translation> <translation id="8463851957836045671">Site-ul este rapid</translation> <translation id="851751545965956758">Blochează conectarea site-urilor la dispozitive</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Blochează cookie-urile pentru un anumit site.</translation> <translation id="8959122750345127698">Navigarea nu este accesibilă: <ph name="URL" /></translation> <translation id="9019902583201351841">Gestionat de părinții tăi</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Accesează microfonul</translation> <translation id="965817943346481315">Blochează dacă site-ul afișează anunțuri deranjante sau înșelătoare (recomandat)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ru.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ru.xtb index eca2f47c92a..bd6a7aa595f 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ru.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ru.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Далее</translation> <translation id="1242008676835033345">Встроено на сайте <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Остановить</translation> +<translation id="1289742167380433257">В целях экономии трафика изображения на странице были оптимизированы.</translation> <translation id="129382876167171263">Здесь появятся файлы, сохраненные сайтами.</translation> <translation id="1364532808393826295"><ph name="APP_NAME" />: "<ph name="NOTIFICATION_MESSAGE" />".</translation> <translation id="1369915414381695676">Добавлен сайт <ph name="SITE_NAME" /></translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Запрашивать для сайтов разрешение на создание 3D-карты места, в котором вы находитесь, и отслеживание положения камеры (рекомендуется)</translation> <translation id="2212565012507486665">Разрешить файлы cookie</translation> <translation id="2289270750774289114">Запрашивать для сайтов разрешение на поиск Bluetooth-устройств поблизости (рекомендуется)</translation> +<translation id="2315043854645842844">Сертификат, выбранный клиентом, не поддерживается операционной системой.</translation> <translation id="2359808026110333948">Продолжить</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> МБ</translation> <translation id="2434158240863470628">Скачивание завершено <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Скопировано</translation> <translation id="2822354292072154809">Сбросить разрешения для сайта <ph name="CHOSEN_OBJECT_NAME" />?</translation> <translation id="2870560284913253234">Сайт</translation> +<translation id="2874939134665556319">Предыдущий трек</translation> <translation id="2910701580606108292">Запрашивать разрешение на воспроизведение защищенного контента</translation> <translation id="2913331724188855103">Разрешить сайтам сохранять и читать файлы cookie (рекомендуется)</translation> <translation id="2968755619301702150">Просмотр сертификатов</translation> <translation id="300526633675317032">Будут удалены все данные сайтов (<ph name="SIZE_IN_KB" />).</translation> +<translation id="301521992641321250">Заблокировано автоматически</translation> <translation id="3115898365077584848">Показать информацию</translation> <translation id="3123473560110926937">Заблокировано на некоторых сайтах</translation> <translation id="3190152372525844641">Разрешения для Chrome можно предоставить в <ph name="BEGIN_LINK" />настройках Android<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Фоновая синхронизация</translation> <translation id="3822502789641063741">Удалить данные сайтов?</translation> <translation id="385051799172605136">Назад</translation> +<translation id="3859306556332390985">Перемотать вперед</translation> <translation id="3955193568934677022">Разрешить сайтам воспроизводить защищенный контент (рекомендуется)</translation> <translation id="3987993985790029246">Копировать ссылку</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> из ?</translation> <translation id="4002066346123236978">Название</translation> <translation id="4008040567710660924">Разрешить определенному сайту сохранять файлы cookie.</translation> +<translation id="4046123991198612571">Следующий трек</translation> <translation id="4165986682804962316">Настройки сайтов</translation> <translation id="4226663524361240545">Вибрация при получении уведомлений</translation> <translation id="4242533952199664413">Открыть настройки</translation> <translation id="4259722352634471385">Навигация заблокирована: <ph name="URL" /></translation> <translation id="4278390842282768270">Разрешено</translation> +<translation id="429312253194641664">На сайте воспроизводятся медиафайлы</translation> <translation id="4433925000917964731">Lite-версия страницы получена с помощью Google</translation> <translation id="4434045419905280838">Всплывающие окна и переадресация</translation> <translation id="445467742685312942">Разрешить сайтам воспроизводить защищенный контент</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Отозвать все разрешения для устройства</translation> <translation id="4964199952259983386">Чтобы браузер Chrome мог использовать дополненную реальность, также предоставьте доступ к камере в <ph name="BEGIN_LINK" />настройках Android<ph name="END_LINK" />.</translation> <translation id="497421865427891073">Вперед</translation> +<translation id="4996978546172906250">Способ отправки</translation> <translation id="5039804452771397117">Разрешить</translation> <translation id="5048398596102334565">Предоставить сайтам доступ к датчикам движения (рекомендуется)</translation> <translation id="5063480226653192405">Использование</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Удалить</translation> <translation id="6697925417670533197">Текущие скачивания</translation> <translation id="6746124502594467657">Переместить вниз</translation> +<translation id="6766622839693428701">Проведите вниз, чтобы закрыть панель.</translation> <translation id="6782111308708962316">Запретить сторонним веб-сайтам сохранять и просматривать файлы cookie</translation> +<translation id="6790428901817661496">Воспроизвести</translation> <translation id="6818926723028410516">Выберите объекты</translation> <translation id="6864395892908308021">Это устройство не поддерживает NFC.</translation> <translation id="6910211073230771657">Удалено</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Сайт использует вашу камеру</translation> <translation id="7817023149356982970">Вы выйдете из аккаунта на этом сайте.</translation> <translation id="7828557259026017104">Когда вы посещаете сайты, они создают файлы cookie для сохранения настроек и других пользовательских данных. Сторонние файлы cookie создаются другими сайтами, которые размещают свой контент (например, объявления или изображения) на просматриваемых вами веб-страницах.</translation> +<translation id="7835852323729233924">Воспроизведение медиаконтента</translation> <translation id="7846076177841592234">Отменить выбор</translation> <translation id="7846621471902887024">Вы выйдете из аккаунта на всех сайтах.</translation> <translation id="7882806643839505685">Включить звуки на определенном сайте.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Вы уверены, что хотите удалить все данные этого веб-сайта, включая файлы cookie, и сбросить заданные разрешения?</translation> <translation id="8007176423574883786">Отключено для этого устройства</translation> <translation id="802154636333426148">Ошибка скачивания</translation> +<translation id="8068648041423924542">Невозможно выбрать сертификат.</translation> <translation id="8087000398470557479">Контент с сайта <ph name="DOMAIN_NAME" />. Получен с помощью Google.</translation> <translation id="8116925261070264013">Сайты с отключенным звуком</translation> <translation id="8131740175452115882">Подтвердить</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Сайт использует вашу камеру и микрофон</translation> <translation id="8380167699614421159">Этот сайт показывает навязчивую или вводящую в заблуждение рекламу</translation> <translation id="8394832520002899662">Нажмите, чтобы вернуться на сайт.</translation> +<translation id="8425213833346101688">Изменить</translation> +<translation id="8441146129660941386">Перемотать назад</translation> <translation id="8447861592752582886">Отключить доступ к устройству</translation> <translation id="8463851957836045671">Сайт работает быстро</translation> <translation id="851751545965956758">Не разрешать сайтам подключаться к устройствам</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Блокировать файлы cookie для определенного сайта.</translation> <translation id="8959122750345127698">Страница не найдена: <ph name="URL" /></translation> <translation id="9019902583201351841">Управляется вашими родителями</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Доступ к микрофону</translation> <translation id="965817943346481315">Блокировать, если сайт показывает навязчивую или вводящую в заблуждение рекламу (рекомендуется)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_si.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_si.xtb index d1171b274f0..861d7e8878b 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_si.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_si.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">ඊළඟ</translation> <translation id="1242008676835033345"><ph name="WEBSITE_URL" /> මත කාවද්දන්න</translation> <translation id="1272079795634619415">නවතන්න</translation> +<translation id="1289742167380433257">ඔබේ දත්ත සුරැකීමට, මෙම පිටුවේ රූප Google මගින් ප්රශස්ත කර ඇත.</translation> <translation id="129382876167171263">වෙබ් අඩවිවලින් සුරකින ලද ගොනු මෙහි දිස් වෙති</translation> <translation id="1364532808393826295"><ph name="APP_NAME" />, <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">අඩවි <ph name="SITE_NAME" /> එක් කරන ලදී</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">වෙබ් අඩවිවලට ඔබේ වටපිටාවේ ත්රිමාන සිතියමක් සෑදීමට හෝ කැමරා ස්ථානය හඹා යෑමට ඉඩ දීමට පෙර අසන්න (නිර්දේශිතයි)</translation> <translation id="2212565012507486665">කුකීවලට ඉඩ දෙන්න</translation> <translation id="2289270750774289114">වෙබ් අඩවියකට අවට බ්ලූටූත් උපාංග සොයා ගැනීමට අවශ්ය වූ විට අසන්න (නිර්දේශිතයි)</translation> +<translation id="2315043854645842844">මෙහෙයුම් පද්ධතිය සේවාලාභී පැත්තේ සහතික තේරීමට සහාය නොදක්වයි.</translation> <translation id="2359808026110333948">කරගෙන යන්න</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">බාගැනීම සම්පූර්ණයි <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">පිටපත් කරන ලදි</translation> <translation id="2822354292072154809">ඔබට <ph name="CHOSEN_OBJECT_NAME" /> සඳහා සියලුම වෙබ් අඩවි අවසර යළි සැකසිය යුතු බව ඔබට තහවුරුද?</translation> <translation id="2870560284913253234">අඩවිය</translation> +<translation id="2874939134665556319">පෙර ඛණ්ඩය</translation> <translation id="2910701580606108292">ආරක්ෂිත අන්තර්ගත වාදනය කිරීමට ඉඩ දීමට පෙර විමසන්න (නිර්දේශිතයි)</translation> <translation id="2913331724188855103">අඩවි වලට කුකී දත්ත සුරැකීමට සහ කුකී දත්ත කියවන්න (නිර්දේශිතයි)</translation> <translation id="2968755619301702150">සහතික දක්වනය</translation> <translation id="300526633675317032">මෙය වෙබ් අඩවි ආචයනයේ සියලු <ph name="SIZE_IN_KB" /> හිස් කරනු ඇත.</translation> +<translation id="301521992641321250">ස්වයංක්රියව අවහිර කර ඇත</translation> <translation id="3115898365077584848">තතු පෙන්වන්න</translation> <translation id="3123473560110926937">සමහර වෙබ් අඩවිවල අවහිර කෙරේ</translation> <translation id="3190152372525844641">Chrome සඳහා අවසර ප්රවේශය <ph name="BEGIN_LINK" />Android සැකසීම්<ph name="END_LINK" /> තුළ ක්රියාත්මක කරන්න.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">පසුබිමෙහි සමමුහුර්තකරණය</translation> <translation id="3822502789641063741">අඩවි ආචයනය හිස් කරනවා ද?</translation> <translation id="385051799172605136">ආපසු</translation> +<translation id="3859306556332390985">ඉදිරියට සොයන්න</translation> <translation id="3955193568934677022">අඩවිවලට ආරක්ෂිත අන්තර්ගතය වාදනය කිරීමට ඉඩ දෙන්න (නිර්දේශිතයි)</translation> <translation id="3987993985790029246">සබැඳිය පිටපත් කරන්න</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">සිරස්තලය</translation> <translation id="4008040567710660924">නිශ්චිත අඩවියක් සඳහා කුකීවලට ඉඩ දෙන්න.</translation> +<translation id="4046123991198612571">ඊළඟ ඛණ්ඩය</translation> <translation id="4165986682804962316">අඩවි සැකසුම්</translation> <translation id="4226663524361240545">දැනුම්දීම් උපාංගය කම්පනය කළ හැක</translation> <translation id="4242533952199664413">සැකසීම් විවෘත කරන්න</translation> <translation id="4259722352634471385">සංචාලනය අවහිර කර ඇත: <ph name="URL" /></translation> <translation id="4278390842282768270">ඉඩ දුන්</translation> +<translation id="429312253194641664">වෙබ් අඩවියක් මාධ්ය ධාවන කරයි</translation> <translation id="4433925000917964731">Google විසින් දෙනු ලබන සැහැල්ලු පිටුව</translation> <translation id="4434045419905280838">උත්පතන සහ හරවා යැවීම්</translation> <translation id="445467742685312942">මෙම වෙබ් අඩවියට ආරක්ෂිත අන්තර්ගතය ධාවන කිරීමට ඉඩ දෙන්න.</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">උපාංගය සඳහා සියලුම අවසර අහෝසි කරන්න</translation> <translation id="4964199952259983386">Chrome හට AR භාවිත කිරීමට ඉඩ දීමට, <ph name="BEGIN_LINK" />Android සැකසීම්<ph name="END_LINK" /> තුළ කැමරාව ද සක්රීය කරන්න.</translation> <translation id="497421865427891073">ඉදිරියට යන්න</translation> +<translation id="4996978546172906250">හරහා බෙදාගන්න</translation> <translation id="5039804452771397117">ඉඩදෙන්න</translation> <translation id="5048398596102334565">වෙබ් අඩවිවලට චලන සංවේදකවලට ප්රවේශ වීමට ඉඩ දෙන්න (නිර්දේශිතයි)</translation> <translation id="5063480226653192405">භාවිතය</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">මකන්න</translation> <translation id="6697925417670533197">ක්රියාත්මක බාගැනීම්</translation> <translation id="6746124502594467657">පහළට ගෙන යන්න</translation> +<translation id="6766622839693428701">වැසීමට පහළට ස්වයිප් කරන්න.</translation> <translation id="6782111308708962316">තෙවන-පාර්ශ්ව වෙබ් අඩවි කුකී දත්ත සුරැකීම සහ කියවීම වළක්වන්න</translation> +<translation id="6790428901817661496">වාදනය කරන්න</translation> <translation id="6818926723028410516">අයිතම තෝරන්න</translation> <translation id="6864395892908308021">මෙම උපාංගය NFC කියවිය නොහැක</translation> <translation id="6910211073230771657">මකාදැමූ</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">වෙබ් අඩවියක් ඔබේ කැමරාව භාවිත කරයි</translation> <translation id="7817023149356982970">ඔබ මෙම වෙබ් අඩවියන් වරනු ලැබේ.</translation> <translation id="7828557259026017104">කුකීස් යනු ඔබ පැමිණෙන වෙබ් අඩවිවලින් නිර්මාණ කෙරෙන ගොනු වේ. වෙබ් අඩවි ඔබේ මනාප මතක තබා ගැනීමට ඒවා භාවිත කරයි. තෙවන පාර්ශ්ව කුකී වෙනත් වෙබ් අඩවිවලින් නිර්මාණ කෙරේ. මෙම වෙබ් පිටුවලට ඔබ පැමිණෙන වෙබ් අඩවිය මත ඔබ දකින රූප හෝ දැන්වීම් වැනි සමහර අන්තර්ගත හිමි වේ.</translation> +<translation id="7835852323729233924">මාධ්ය ධාවනය</translation> <translation id="7846076177841592234">තේරීම අවලංගු කරන්න</translation> <translation id="7846621471902887024">ඔබ සියලුම වෙබ් අඩවිවලින් වරනු ලැබේ.</translation> <translation id="7882806643839505685">නිශ්චිත අඩවියක් සඳහා ශබ්දයට ඉඩ දෙන්න.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">කුකීස් ඇතුළු සියලු පෙදෙසි දත්ත හිස් කිරීමට අවශ්ය යැයි සහ මෙම වෙබ් අඩවිය සඳහා සියලු අවසර නැවත සැකසිය යුතු යැයි ඔබට විශ්වාස ද?</translation> <translation id="8007176423574883786">මෙම උපාංගය සඳහා ක්රියාවිරහිත කරන ලදී.</translation> <translation id="802154636333426148">බාගැනීම අසමත් විය</translation> +<translation id="8068648041423924542">සහතිකය තේරීමට නොහැකිය.</translation> <translation id="8087000398470557479">මෙම අන්තර්ගතය Google විසින් බෙදාහරින, <ph name="DOMAIN_NAME" /> වෙතින් වේ.</translation> <translation id="8116925261070264013">නිහඬයි</translation> <translation id="8131740175452115882">තහවුරු කරන්න</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">වෙබ් අඩවියක් ඔබේ කැමරාව සහ මයික්රොෆෝනය භාවිත කරයි</translation> <translation id="8380167699614421159">මෙම වෙබ් අඩවිය ආක්රමණික හෝ නොමඟ යවන දැන්වීම් පෙන්වයි</translation> <translation id="8394832520002899662">වෙබ් අඩවියට ආපසු යාමට තට්ටු කරන්න</translation> +<translation id="8425213833346101688">වෙනස් කරන්න</translation> +<translation id="8441146129660941386">පසුපසට සොයන්න</translation> <translation id="8447861592752582886">උපාංගයේ අවසර අහෝසි කරන්න</translation> <translation id="8463851957836045671">අඩවිය වේගවත් ය</translation> <translation id="851751545965956758">අඩවි උපාංගවලට සම්බන්ධ වීම අවහිර කරන්න</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">නිශ්චිත අඩවියක් සඳහා කුකී අවහිර කරන්න.</translation> <translation id="8959122750345127698">සංචාලනය වෙත ළඟා විය නොහැකිය: <ph name="URL" /></translation> <translation id="9019902583201351841">ඔබේ දෙමව්පියන් පාලනය කරයි</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">ඔබේ මයික්රෆෝනය වෙත ප්රවේශ වන්න</translation> <translation id="965817943346481315">වෙබ් අඩවිය ආක්රමණශීලී හෝ නොමඟ යවන දැන්වීම් පෙන්වන්නේ නම් අවහිර කරන්න (නිර්දේශිතයි)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_sk.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_sk.xtb index 8dd182b734b..43f8280592a 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_sk.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_sk.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Ďalej</translation> <translation id="1242008676835033345">Vložené na webe <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Zastaviť</translation> +<translation id="1289742167380433257">Google optimalizoval obrázky tejto stránky, aby vám ušetril dáta.</translation> <translation id="129382876167171263">Tu sa zobrazia súbory uložené webmi</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> – <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Boli pridané stránky <ph name="SITE_NAME" /></translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Opýtať sa, či chcete povoliť webom vytvoriť 3D mapu vášho okolia alebo sledovať umiestnenie kamier (odporúčané)</translation> <translation id="2212565012507486665">Povoliť súbory cookie</translation> <translation id="2289270750774289114">Opýtať sa, keď chce web objavovať zariadenia Bluetooth v okolí (odporúčané)</translation> +<translation id="2315043854645842844">Operačný systém nepodporuje výber certifikátu na strane klienta.</translation> <translation id="2359808026110333948">Pokračovať</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">Sťahovanie bolo dokončené <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Skopírované</translation> <translation id="2822354292072154809">Naozaj chcete resetovať všetky povolenia webu pre <ph name="CHOSEN_OBJECT_NAME" />?</translation> <translation id="2870560284913253234">Web</translation> +<translation id="2874939134665556319">Predchádzajúca skladba</translation> <translation id="2910701580606108292">Pýtať sa, či chcete povoliť webu prehrávať chránený obsah</translation> <translation id="2913331724188855103">Povoliť webom ukladať a čítať súbory cookie (odporučané)</translation> <translation id="2968755619301702150">Zobrazovač certifikátov</translation> <translation id="300526633675317032">Vymažete celé úložisko webu (<ph name="SIZE_IN_KB" />).</translation> +<translation id="301521992641321250">Automaticky blokované</translation> <translation id="3115898365077584848">Zobraziť informácie</translation> <translation id="3123473560110926937">Blokované na niektorých weboch</translation> <translation id="3190152372525844641">Zapnite povolenia pre Chrome v <ph name="BEGIN_LINK" />nastaveniach Androidu<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Synchronizácia na pozadí</translation> <translation id="3822502789641063741">Vymazať úložisko webov?</translation> <translation id="385051799172605136">Späť</translation> +<translation id="3859306556332390985">Pretočiť dopredu</translation> <translation id="3955193568934677022">Povoliť webom prehrávať chránený obsah (odporúčané)</translation> <translation id="3987993985790029246">Kopírovať odkaz</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">Názov</translation> <translation id="4008040567710660924">Povolenie súborov cookie konkrétneho webu</translation> +<translation id="4046123991198612571">Ďalšia skladba</translation> <translation id="4165986682804962316">Nastavenia webu</translation> <translation id="4226663524361240545">Upozornenia môžu pri prijatí na zariadení spustiť vibrovanie</translation> <translation id="4242533952199664413">Otvoriť nastavenia</translation> <translation id="4259722352634471385">Navigácia je zablokovaná: <ph name="URL" /></translation> <translation id="4278390842282768270">Povolené</translation> +<translation id="429312253194641664">Web prehráva médiá</translation> <translation id="4433925000917964731">Zjednodušenú verziu stránky poskytol Google</translation> <translation id="4434045419905280838">Vyskakovacie okná a presmerovania</translation> <translation id="445467742685312942">Povoliť webom prehrávať chránený obsah</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Odvolať všetky povolenia pre zariadenie</translation> <translation id="4964199952259983386">Fotoaparát zapnite aj v <ph name="BEGIN_LINK" />Nastaveniach Androidu<ph name="END_LINK" />, aby mohol Chrome používať RR.</translation> <translation id="497421865427891073">Ďalej</translation> +<translation id="4996978546172906250">Zdieľať</translation> <translation id="5039804452771397117">Povoliť</translation> <translation id="5048398596102334565">Povoliť webom prístup k senzorom pohybu (odporúčané)</translation> <translation id="5063480226653192405">Použitie</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Vymazať</translation> <translation id="6697925417670533197">Práve sťahované položky</translation> <translation id="6746124502594467657">Presunúť nadol</translation> +<translation id="6766622839693428701">Zatvorte potiahnutím dole.</translation> <translation id="6782111308708962316">Brániť webom tretích strán ukladať a čítať súbory cookie</translation> +<translation id="6790428901817661496">Prehrať</translation> <translation id="6818926723028410516">Vyberte položky</translation> <translation id="6864395892908308021">Toto zariadenie nedokáže čítať NFC</translation> <translation id="6910211073230771657">Odstránené</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Váš fotoaparát používa nejaký web</translation> <translation id="7817023149356982970">Systém vás z tohto webu odhlási.</translation> <translation id="7828557259026017104">Súbory cookie sú vytvárané webmi, ktoré navštívite. Pamätajú si pomocou nich vaše predvoľby. Súbory cookie tretích strán sú vytvárané ďalšími webmi. Tieto weby sú vlastníkmi prvkov obsahu, ktorý sa zobrazuje na navštívenej webovej stránke (napríklad reklamy alebo obrázky).</translation> +<translation id="7835852323729233924">Prehrávanie médií</translation> <translation id="7846076177841592234">Zrušiť výber</translation> <translation id="7846621471902887024">Systém vás odhlási zo všetkých webov.</translation> <translation id="7882806643839505685">Povoliť zvuk pre konkrétny web.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Naozaj chcete vymazať všetky miestne dáta tohto webu, vrátane súborov cookie, a resetovať všetky jeho povolenia?</translation> <translation id="8007176423574883786">Vypnuté v tomto zariadení</translation> <translation id="802154636333426148">Stiahnutie zlyhalo</translation> +<translation id="8068648041423924542">Nedá sa vybrať certifikát</translation> <translation id="8087000398470557479">Tento obsah pochádza z domény <ph name="DOMAIN_NAME" /> a bol doručený Googlom.</translation> <translation id="8116925261070264013">Zvuk bol vypnutý</translation> <translation id="8131740175452115882">Potvrdiť</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Váš fotoaparát a mikrofón používa nejaký web</translation> <translation id="8380167699614421159">Tento web zobrazuje obťažujúce alebo zavádzajúce reklamy</translation> <translation id="8394832520002899662">Klepnutím sa vrátite na web</translation> +<translation id="8425213833346101688">Zmeniť</translation> +<translation id="8441146129660941386">Pretočiť dozadu</translation> <translation id="8447861592752582886">Odvolať povolenie pre zariadenie</translation> <translation id="8463851957836045671">Web je rýchly</translation> <translation id="851751545965956758">Zakázať webom pripájať sa k zariadeniam</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Blokovanie súborov cookie konkrétneho webu</translation> <translation id="8959122750345127698">Navigácia je nedostupná: <ph name="URL" /></translation> <translation id="9019902583201351841">Spravované vašimi rodičmi</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Prístup k mikrofónu</translation> <translation id="965817943346481315">Blokovať, ak web zobrazuje obťažujúce alebo zavádzajúce reklamy (odporúčané)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_sl.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_sl.xtb index 389a519e7a9..91cccd984de 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_sl.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_sl.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Naprej</translation> <translation id="1242008676835033345">Vdelano v <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Ustavi</translation> +<translation id="1289742167380433257">Google optimizira slike na tej strani, da prihranite pri prenosu podatkov.</translation> <translation id="129382876167171263">Datoteke, ki jih shranijo spletna mesta, so prikazane tukaj</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> – <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Spletno mesto <ph name="SITE_NAME" /> je bilo dodano</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Vprašaj, preden se spletnim mestom dovoli ustvarjanje 3D-zemljevida vaše okolice ali spremljanje položaja kamere (priporočljivo)</translation> <translation id="2212565012507486665">Dovoli piškotke</translation> <translation id="2289270750774289114">Vprašaj, ko želi spletno mesto odkrivati naprave Bluetooth v bližini (priporočljivo)</translation> +<translation id="2315043854645842844">Operacijski sistem ne podpira izbire potrdila pri odjemalcu.</translation> <translation id="2359808026110333948">Naprej</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">Prenos je končan <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Kopirano</translation> <translation id="2822354292072154809">Ali ste prepričani, da želite ponastaviti vsa dovoljenja za spletna mesta za <ph name="CHOSEN_OBJECT_NAME" />?</translation> <translation id="2870560284913253234">Spletno mesto</translation> +<translation id="2874939134665556319">Prejšnja skladba</translation> <translation id="2910701580606108292">Prikaži poziv, preden se spletnim mestom dovoli predvajanje zaščitene vsebine</translation> <translation id="2913331724188855103">Dovoli spletnim mestom shranjevanje in branje podatkov piškotkov (priporočljivo)</translation> <translation id="2968755619301702150">Pregledovalnik potrdil</translation> <translation id="300526633675317032">S tem bo izbrisanih vseh <ph name="SIZE_IN_KB" /> shranjenih podatkov spletnega mesta.</translation> +<translation id="301521992641321250">Samodejno blokirano</translation> <translation id="3115898365077584848">Pokaži informacije</translation> <translation id="3123473560110926937">Blokirano na nekaterih spletnih mestih</translation> <translation id="3190152372525844641">V <ph name="BEGIN_LINK" />nastavitvah za Android<ph name="END_LINK" /> vklopite dovoljenja za Chrome.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Sinhroniziranje v ozadju</translation> <translation id="3822502789641063741">Izbris shrambe mesta?</translation> <translation id="385051799172605136">Nazaj</translation> +<translation id="3859306556332390985">Išči naprej</translation> <translation id="3955193568934677022">Dovoli spletnim mestom predvajanje zaščitene vsebine (priporočeno)</translation> <translation id="3987993985790029246">Kopiranje povezave</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> <translation id="4002066346123236978">Naslov</translation> <translation id="4008040567710660924">Omogočanje piškotkov za določeno spletno mesto.</translation> +<translation id="4046123991198612571">Naslednja skladba</translation> <translation id="4165986682804962316">Nastavitve spletnega mesta</translation> <translation id="4226663524361240545">Ob prejemanju obvestil naprava morda vibrira</translation> <translation id="4242533952199664413">Odpri nastavitve</translation> <translation id="4259722352634471385">Krmarjenje je blokirano: <ph name="URL" /></translation> <translation id="4278390842282768270">Dovoljeno</translation> +<translation id="429312253194641664">Spletno mesto predvaja predstavnost</translation> <translation id="4433925000917964731">Stran v osnovnem načinu, ki jo je prikazal Google</translation> <translation id="4434045419905280838">Pojavna okna in preusmeritve</translation> <translation id="445467742685312942">Spletnim mestom dovoli predvajanje zaščitene vsebine</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Umik vseh dovoljenj za napravo</translation> <translation id="4964199952259983386">Če želite Chromu dovoliti uporabo razširjene resničnosti, prav tako vklopite fotoaparat v <ph name="BEGIN_LINK" />nastavitvah za Android<ph name="END_LINK" />.</translation> <translation id="497421865427891073">Pojdi naprej</translation> +<translation id="4996978546172906250">Skupna raba prek</translation> <translation id="5039804452771397117">Dovoli</translation> <translation id="5048398596102334565">Spletnim mestom dovoli dostop do tipal gibanja (priporočeno)</translation> <translation id="5063480226653192405">Uporaba</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Izbriši</translation> <translation id="6697925417670533197">Aktivni prenosi</translation> <translation id="6746124502594467657">Premakni dol</translation> +<translation id="6766622839693428701">Povlecite navzdol, da zaprete.</translation> <translation id="6782111308708962316">Drugim spletnim mestom prepreči shranjevanje in branje podatkov piškotkov</translation> +<translation id="6790428901817661496">Predvajanje</translation> <translation id="6818926723028410516">Izberite elemente</translation> <translation id="6864395892908308021">Ta naprava ne podpira NFC-ja</translation> <translation id="6910211073230771657">Izbrisano</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Spletno mesto uporablja kamero</translation> <translation id="7817023149356982970">Odjavljeni boste s tega spletnega mesta.</translation> <translation id="7828557259026017104">Piškotki so datoteke, ki jih ustvarijo spletna mesta, ki jih obiščete. Spletna mesta jih uporabljajo, da si zapomnijo vaše nastavitve. Piškotke drugih spletnih mest ustvarijo druga spletna mesta. Ta spletna mesta imajo v lasti nekatero vsebino, na primer oglase ali slike, ki jo vidite na spletni strani, ki jo obiščete.</translation> +<translation id="7835852323729233924">Predvajanje predstavnosti</translation> <translation id="7846076177841592234">Prekliči izbor</translation> <translation id="7846621471902887024">Odjavljeni boste z vseh spletnih mest.</translation> <translation id="7882806643839505685">Dovolitev zvoka za določeno spletno mesto.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Ali želite res izbrisati vse lokalne podatke, vključno s piškotki, in ponastaviti vsa dovoljenja za to spletno mesto?</translation> <translation id="8007176423574883786">Izklopljeno za to napravo</translation> <translation id="802154636333426148">Prenos ni uspel</translation> +<translation id="8068648041423924542">Izbira potrdila ni mogoča</translation> <translation id="8087000398470557479">Ta vsebina je iz domene <ph name="DOMAIN_NAME" /> in jo prikazuje Google.</translation> <translation id="8116925261070264013">Prezrto</translation> <translation id="8131740175452115882">Potrdi</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Spletno mesto uporablja kamero in mikrofon</translation> <translation id="8380167699614421159">To spletno mesto prikazuje vsiljive ali zavajajoče oglase</translation> <translation id="8394832520002899662">Dotaknite se, če se želite vrniti na spletno mesto</translation> +<translation id="8425213833346101688">Spremeni</translation> +<translation id="8441146129660941386">Išči nazaj</translation> <translation id="8447861592752582886">Umik dovoljenja za dostop do naprave</translation> <translation id="8463851957836045671">Spletno mesto je hitro</translation> <translation id="851751545965956758">Spletnim mestom prepreči povezovanje z napravami</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Blokiranje piškotkov za določeno spletno mesto.</translation> <translation id="8959122750345127698">Krmarjenje ni dosegljivo: <ph name="URL" /></translation> <translation id="9019902583201351841">Upravljajo starši</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Dostop do mikrofona</translation> <translation id="965817943346481315">Blokiraj, če spletno mesto prikazuje vsiljive ali zavajajoče oglase (priporočljivo)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_sq.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_sq.xtb index c827338a314..01c6aadbb76 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_sq.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_sq.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Tjetra</translation> <translation id="1242008676835033345">Integruar në <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Ndalo</translation> +<translation id="1289742167380433257">Për të ruajtur të dhënat, imazhet e kësaj faqeje janë optimizuar nga Google.</translation> <translation id="129382876167171263">Skedarët e ruajtur nga sajtet e uebit shfaqen këtu</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> - <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Sajti <ph name="SITE_NAME" /> u shtua</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Pyet përpara se të lejosh krijimin nga sajtet të një harte 3D të ambientit tënd rrethues ose gjurmimin prej tyre të pozicionit të kamerës (rekomandohet)</translation> <translation id="2212565012507486665">Lejo kukit</translation> <translation id="2289270750774289114">Pyet kur një sajt dëshiron të zbulojë pajisjet Bluetooth në afërsi (rekomandohet)</translation> +<translation id="2315043854645842844">Përzgjedhja e certifikatës nga ana e klientit nuk mbështetet nga sistemi operativ.</translation> <translation id="2359808026110333948">Vazhdo</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">Shkarkimi përfundoi <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Kopjuar</translation> <translation id="2822354292072154809">Je i sigurt që dëshiron t'i rivendosësh të gjitha lejet e sajtit për <ph name="CHOSEN_OBJECT_NAME" />?</translation> <translation id="2870560284913253234">Sajti</translation> +<translation id="2874939134665556319">Kënga e mëparshme</translation> <translation id="2910701580606108292">Pyet përpara se sajtet të lejohen të luajnë përmbajtje të mbrojtura</translation> <translation id="2913331724188855103">Lejo faqet të ruajnë dhe lexojnë të dhënat e kukive (rekomandohet)</translation> <translation id="2968755619301702150">Shikuesi i certifikatave</translation> <translation id="300526633675317032">Kjo do të pastrojë të gjitha <ph name="SIZE_IN_KB" /> të hapësirës ruajtëse të sajtit të uebit.</translation> +<translation id="301521992641321250">Bllokuar automatikisht</translation> <translation id="3115898365077584848">Shfaq informacionin</translation> <translation id="3123473560110926937">Bllokuar në disa sajte</translation> <translation id="3190152372525844641">Aktivizo lejimet për Chrome te <ph name="BEGIN_LINK" />"Cilësimet" e Android<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Sinkronizimi në sfond</translation> <translation id="3822502789641063741">Të pastrohet hapësira ruajtëse e sajtit?</translation> <translation id="385051799172605136">Prapa</translation> +<translation id="3859306556332390985">Kërko përpara</translation> <translation id="3955193568934677022">Lejo që sajtet të luajnë përmbajtje të mbrojtur (rekomandohet)</translation> <translation id="3987993985790029246">Kopjo lidhjen</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">Titulli</translation> <translation id="4008040567710660924">Lejo kukit për një sajt specifik.</translation> +<translation id="4046123991198612571">Kënga tjetër</translation> <translation id="4165986682804962316">Cilësimet e sajtit</translation> <translation id="4226663524361240545">Njoftimet mund të bëjnë që pajisja të dridhet</translation> <translation id="4242533952199664413">Hap cilësimet</translation> <translation id="4259722352634471385">Lundrimi është bllokuar: <ph name="URL" /></translation> <translation id="4278390842282768270">Të lejuara</translation> +<translation id="429312253194641664">Një sajt po luan media</translation> <translation id="4433925000917964731">Faqja e lehtë ofrohet nga Google.</translation> <translation id="4434045419905280838">Dritaret kërcyese dhe ridrejtimet</translation> <translation id="445467742685312942">Lejo sajtet të luajnë përmbajtje të mbrojtura</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Anulo të gjitha lejet për pajisjen</translation> <translation id="4964199952259983386">Për të lejuar që Chrome të përdorë AR, aktivizo gjithashtu kamerën në <ph name="BEGIN_LINK" />Cilësimet e Android<ph name="END_LINK" />.</translation> <translation id="497421865427891073">Vazhdo përpara</translation> +<translation id="4996978546172906250">Ndaje nëpërmjet</translation> <translation id="5039804452771397117">Lejo</translation> <translation id="5048398596102334565">Lejoju faqeve të të hapin sensorët e lëvizjes (rekomandohet)</translation> <translation id="5063480226653192405">Përdorimi</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Pastro</translation> <translation id="6697925417670533197">Shkarkimet aktive</translation> <translation id="6746124502594467657">Lëviz poshtë</translation> +<translation id="6766622839693428701">Rrëshqit shpejt poshtë për ta mbyllur.</translation> <translation id="6782111308708962316">Parandalo sajtet e uebit të palëve të treta që të ruajnë dhe lexojnë të dhënat e kukive</translation> +<translation id="6790428901817661496">Luaj</translation> <translation id="6818926723028410516">Zgjidh artikujt</translation> <translation id="6864395892908308021">Kjo pajisje nuk mund të lexojë NFC-në</translation> <translation id="6910211073230771657">Fshirë</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Një sajt po përdor kamerën tënde</translation> <translation id="7817023149356982970">Do të dalësh nga ky sajt.</translation> <translation id="7828557259026017104">Kukit janë skedarë të krijuar nga sajtet e uebit që viziton ti. Përdori ato për të kujtuar preferencat e tua. Kukit e palëve të treta krijohen nga sajte të tjera. Këto sajte zotërojnë disa nga përmbajtjet, si p.sh. reklamat ose imazhet që ti shikon në faqen e uebit që viziton.</translation> +<translation id="7835852323729233924">Po luan media</translation> <translation id="7846076177841592234">Anulo zgjedhjen</translation> <translation id="7846621471902887024">Do të dalësh nga të gjitha sajtet.</translation> <translation id="7882806643839505685">Lejo tingullin për një sajt specifik.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Je i sigurt që dëshiron t'i pastrosh të gjitha të dhënat lokale, duke përfshirë kukit, dhe të rivendosësh të gjitha lejet për këtë sajt uebi?</translation> <translation id="8007176423574883786">E çaktivizuar për këtë pajisje</translation> <translation id="802154636333426148">Shkarkimi dështoi</translation> +<translation id="8068648041423924542">Nuk mund të zgjidhet certifikata.</translation> <translation id="8087000398470557479">Kjo përmbajtje është nga <ph name="DOMAIN_NAME" />, dërguar nga Google.</translation> <translation id="8116925261070264013">Zëri i çaktivizuar</translation> <translation id="8131740175452115882">Konfirmo</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Një sajt po përdor kamerën dhe mikrofonin tënd</translation> <translation id="8380167699614421159">Ky sajt shfaq reklama ndërhyrëse ose mashtruese</translation> <translation id="8394832520002899662">Trokit për t'u kthyer në sajt</translation> +<translation id="8425213833346101688">Ndrysho</translation> +<translation id="8441146129660941386">Kërko prapa</translation> <translation id="8447861592752582886">Revoko lejen e pajisjes</translation> <translation id="8463851957836045671">Sajti është i shpejtë</translation> <translation id="851751545965956758">Blloko lidhjen e sajteve me pajisjet</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Blloko kukit për një sajt specifik.</translation> <translation id="8959122750345127698">Lundrimi është i paarritshëm: <ph name="URL" /></translation> <translation id="9019902583201351841">Menaxhuar nga prindërit e tu</translation> +<translation id="9074739597929991885">Bluetooth-i</translation> <translation id="945632385593298557">Qasu te mikrofoni</translation> <translation id="965817943346481315">Blloko nëse sajti shfaq reklama ndërhyrëse ose mashtruese (rekomandohet)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_sr-Latn.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_sr-Latn.xtb index 75825ffd0bc..9477e75bb85 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_sr-Latn.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_sr-Latn.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Dalje</translation> <translation id="1242008676835033345">Ugrađeno u sajt <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Zaustavi</translation> +<translation id="1289742167380433257">Da bi se smanjilo korišćenje podataka, Google je optimizovao slike na ovoj stranici.</translation> <translation id="129382876167171263">Datoteke koje su sačuvali veb-sajtovi prikazuju se ovde</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> – <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Sajt <ph name="SITE_NAME" /> je dodat</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Pre nego što dozvolite sajtovima da prave 3D mapu okruženja ili prate položaj kamere prikazuje se upit (preporučeno)</translation> <translation id="2212565012507486665">Dozvoli kolačiće</translation> <translation id="2289270750774289114">Pitaj kada sajt želi da otkrije Bluetooth uređaje u blizini (preporučeno)</translation> +<translation id="2315043854645842844">Operativni sistem ne podržava izbor sertifikata za klijenta.</translation> <translation id="2359808026110333948">Nastavite</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">Preuzimanje je završeno <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Kopirano</translation> <translation id="2822354292072154809">Želite li stvarno da resetujete sve dozvole za sajt za <ph name="CHOSEN_OBJECT_NAME" />?</translation> <translation id="2870560284913253234">Sajt</translation> +<translation id="2874939134665556319">Prethodna pesma</translation> <translation id="2910701580606108292">Pitaj pre nego što dozvoliš sajtovima da puštaju zaštićeni sadržaj</translation> <translation id="2913331724188855103">Dozvoli sajtovima da čuvaju i čitaju podatke kolačića (preporučuje se)</translation> <translation id="2968755619301702150">Prikazivač sertifikata</translation> <translation id="300526633675317032">Ovim ćete obrisati ceo memorijski prostor veb-sajta od <ph name="SIZE_IN_KB" />.</translation> +<translation id="301521992641321250">Automatski je blokirano</translation> <translation id="3115898365077584848">Prikaži informacije</translation> <translation id="3123473560110926937">Blokirano na nekim sajtovima</translation> <translation id="3190152372525844641">Uključite dozvole za Chrome u <ph name="BEGIN_LINK" />Android podešavanjima<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Sinhronizacija u pozadini</translation> <translation id="3822502789641063741">Brišete memoriju sajta?</translation> <translation id="385051799172605136">Nazad</translation> +<translation id="3859306556332390985">Premotaj unapred</translation> <translation id="3955193568934677022">Dozvoli sajtovima da puštaju zaštićeni sadržaj (preporučeno)</translation> <translation id="3987993985790029246">Kopiraj link</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> <translation id="4002066346123236978">Naslov</translation> <translation id="4008040567710660924">Omogućava kolačiće za određeni sajt.</translation> +<translation id="4046123991198612571">Sledeća pesma</translation> <translation id="4165986682804962316">Podešavanja sajta</translation> <translation id="4226663524361240545">Uređaj će vibrirati kada primate obaveštenja</translation> <translation id="4242533952199664413">Otvori podešavanja</translation> <translation id="4259722352634471385">Navigacija je blokirana: <ph name="URL" /></translation> <translation id="4278390842282768270">Dozvoljeno</translation> +<translation id="429312253194641664">Sajt pušta medijski sadržaj</translation> <translation id="4433925000917964731">Pojednostavljenu stranicu pruža Google</translation> <translation id="4434045419905280838">Iskačući prozori i preusmeravanja</translation> <translation id="445467742685312942">Dozvolite sajtovima da puštaju zaštićeni sadržaj</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Opozovite sve dozvole za uređaj</translation> <translation id="4964199952259983386">Da biste dozvolili da Chrome koristi PR, uključite i kameru u <ph name="BEGIN_LINK" />Android podešavanjima<ph name="END_LINK" />.</translation> <translation id="497421865427891073">Kretanje unapred</translation> +<translation id="4996978546172906250">Deljenje preko</translation> <translation id="5039804452771397117">Dozvoli</translation> <translation id="5048398596102334565">Dozvoli sajtovima da pristupaju senzorima za pokret (preporučeno)</translation> <translation id="5063480226653192405">Korišćenje</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Obriši</translation> <translation id="6697925417670533197">Aktivna preuzimanja</translation> <translation id="6746124502594467657">Premesti nadole</translation> +<translation id="6766622839693428701">Prevucite nadole da biste zatvorili.</translation> <translation id="6782111308708962316">Spreči veb-sajtove treće strane da čuvaju i čitaju podatke kolačića</translation> +<translation id="6790428901817661496">Pusti</translation> <translation id="6818926723028410516">Izaberite stavke</translation> <translation id="6864395892908308021">Ovaj uređaj ne može da čita NFC</translation> <translation id="6910211073230771657">Izbrisano</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Sajt koristi kameru</translation> <translation id="7817023149356982970">Odjavićete se sa ovog sajta.</translation> <translation id="7828557259026017104">Kolačići su datoteke koje prave veb-sajtovi koje posećujete. Sajtovi ih koriste da bi zapamtili vaša podešavanja. Kolačiće treće strane prave drugi sajtovi. Ti sajtovi su vlasnici delova sadržaja koji vidite na posećenoj veb-stranici, poput oglasa ili slika.</translation> +<translation id="7835852323729233924">Reprodukcija medija</translation> <translation id="7846076177841592234">Otkaži izbor</translation> <translation id="7846621471902887024">Odjavićete se sa svih sajtova.</translation> <translation id="7882806643839505685">Dozvoli zvuk za određeni sajt.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Želite li stvarno da obrišete sve lokalne podatke, uključujući kolačiće, i resetujete sve dozvole za ovaj veb-sajt?</translation> <translation id="8007176423574883786">Isključeno je za ovaj uređaj</translation> <translation id="802154636333426148">Preuzimanje nije uspelo</translation> +<translation id="8068648041423924542">Nije moguće izabrati sertifikat.</translation> <translation id="8087000398470557479">Ovaj sadržaj je sa <ph name="DOMAIN_NAME" />, prikazuje Google.</translation> <translation id="8116925261070264013">Zvuk je isključen</translation> <translation id="8131740175452115882">Potvrdi</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Sajt koristi kameru i mikrofon</translation> <translation id="8380167699614421159">Ovaj sajt prikazuje oglase koji ometaju aktivnosti ili obmanjujuće oglase</translation> <translation id="8394832520002899662">Dodirnite da biste se vratili na sajt</translation> +<translation id="8425213833346101688">Promeni</translation> +<translation id="8441146129660941386">Premotaj unazad</translation> <translation id="8447861592752582886">Opozovi dozvolu za uređaj</translation> <translation id="8463851957836045671">Sajt je brz</translation> <translation id="851751545965956758">Onemogući sajtovima da se povezuju sa uređajima</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Blokirajte kolačiće za određeni sajt.</translation> <translation id="8959122750345127698">Navigacija je nedostupna: <ph name="URL" /></translation> <translation id="9019902583201351841">Ovim upravljaju tvoji roditelji</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Pristup mikrofonu</translation> <translation id="965817943346481315">Blokiraj ako sajt prikazuje oglase koji ometaju aktivnosti ili obmanjujuće oglase (preporučeno)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_sr.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_sr.xtb index c1c0fbad00e..1ecb4df00f0 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_sr.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_sr.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Даље</translation> <translation id="1242008676835033345">Уграђено у сајт <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Заустави</translation> +<translation id="1289742167380433257">Да би се смањило коришћење података, Google је оптимизовао слике на овој страници.</translation> <translation id="129382876167171263">Датотеке које су сачували веб-сајтови приказују се овде</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> – <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Сајт <ph name="SITE_NAME" /> је додат</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Пре него што дозволите сајтовима да праве 3D мапу окружења или прате положај камере приказује се упит (препоручено)</translation> <translation id="2212565012507486665">Дозволи колачиће</translation> <translation id="2289270750774289114">Питај када сајт жели да открије Bluetooth уређаје у близини (препоручено)</translation> +<translation id="2315043854645842844">Оперативни систем не подржава избор сертификата за клијента.</translation> <translation id="2359808026110333948">Наставите</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">Преузимање је завршено <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Копирано</translation> <translation id="2822354292072154809">Желите ли стварно да ресетујете све дозволе за сајт за <ph name="CHOSEN_OBJECT_NAME" />?</translation> <translation id="2870560284913253234">Сајт</translation> +<translation id="2874939134665556319">Претходна песма</translation> <translation id="2910701580606108292">Питај пре него што дозволиш сајтовима да пуштају заштићени садржај</translation> <translation id="2913331724188855103">Дозволи сајтовима да чувају и читају податке колачића (препоручује се)</translation> <translation id="2968755619301702150">Приказивач сертификата</translation> <translation id="300526633675317032">Овим ћете обрисати цео меморијски простор веб-сајта од <ph name="SIZE_IN_KB" />.</translation> +<translation id="301521992641321250">Аутоматски је блокирано</translation> <translation id="3115898365077584848">Прикажи информације</translation> <translation id="3123473560110926937">Блокирано на неким сајтовима</translation> <translation id="3190152372525844641">Укључите дозволе за Chrome у <ph name="BEGIN_LINK" />Android подешавањима<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Синхронизација у позадини</translation> <translation id="3822502789641063741">Бришете меморију сајта?</translation> <translation id="385051799172605136">Назад</translation> +<translation id="3859306556332390985">Премотај унапред</translation> <translation id="3955193568934677022">Дозволи сајтовима да пуштају заштићени садржај (препоручено)</translation> <translation id="3987993985790029246">Копирај линк</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> <translation id="4002066346123236978">Наслов</translation> <translation id="4008040567710660924">Омогућава колачиће за одређени сајт.</translation> +<translation id="4046123991198612571">Следећа песма</translation> <translation id="4165986682804962316">Подешавања сајта</translation> <translation id="4226663524361240545">Уређај ће вибрирати када примате обавештења</translation> <translation id="4242533952199664413">Отвори подешавања</translation> <translation id="4259722352634471385">Навигација је блокирана: <ph name="URL" /></translation> <translation id="4278390842282768270">Дозвољено</translation> +<translation id="429312253194641664">Сајт пушта медијски садржај</translation> <translation id="4433925000917964731">Поједностављену страницу пружа Google</translation> <translation id="4434045419905280838">Искачући прозори и преусмеравања</translation> <translation id="445467742685312942">Дозволите сајтовима да пуштају заштићени садржај</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Опозовите све дозволе за уређај</translation> <translation id="4964199952259983386">Да бисте дозволили да Chrome користи ПР, укључите и камеру у <ph name="BEGIN_LINK" />Android подешавањима<ph name="END_LINK" />.</translation> <translation id="497421865427891073">Кретање унапред</translation> +<translation id="4996978546172906250">Дељење преко</translation> <translation id="5039804452771397117">Дозволи</translation> <translation id="5048398596102334565">Дозволи сајтовима да приступају сензорима за покрет (препоручено)</translation> <translation id="5063480226653192405">Коришћење</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Обриши</translation> <translation id="6697925417670533197">Активна преузимања</translation> <translation id="6746124502594467657">Премести надоле</translation> +<translation id="6766622839693428701">Превуците надоле да бисте затворили.</translation> <translation id="6782111308708962316">Спречи веб-сајтове треће стране да чувају и читају податке колачића</translation> +<translation id="6790428901817661496">Пусти</translation> <translation id="6818926723028410516">Изаберите ставке</translation> <translation id="6864395892908308021">Овај уређај не може да чита NFC</translation> <translation id="6910211073230771657">Избрисано</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Сајт користи камеру</translation> <translation id="7817023149356982970">Одјавићете се са овог сајта.</translation> <translation id="7828557259026017104">Колачићи су датотеке које праве веб-сајтови које посећујете. Сајтови их користе да би запамтили ваша подешавања. Колачиће треће стране праве други сајтови. Ти сајтови су власници делова садржаја који видите на посећеној веб-страници, попут огласа или слика.</translation> +<translation id="7835852323729233924">Репродукција медија</translation> <translation id="7846076177841592234">Откажи избор</translation> <translation id="7846621471902887024">Одјавићете се са свих сајтова.</translation> <translation id="7882806643839505685">Дозволи звук за одређени сајт.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Желите ли стварно да обришете све локалне податке, укључујући колачиће, и ресетујете све дозволе за овај веб-сајт?</translation> <translation id="8007176423574883786">Искључено је за овај уређај</translation> <translation id="802154636333426148">Преузимање није успело</translation> +<translation id="8068648041423924542">Није могуће изабрати сертификат.</translation> <translation id="8087000398470557479">Овај садржај је са <ph name="DOMAIN_NAME" />, приказује Google.</translation> <translation id="8116925261070264013">Звук је искључен</translation> <translation id="8131740175452115882">Потврди</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Сајт користи камеру и микрофон</translation> <translation id="8380167699614421159">Овај сајт приказује огласе који ометају активности или обмањујуће огласе</translation> <translation id="8394832520002899662">Додирните да бисте се вратили на сајт</translation> +<translation id="8425213833346101688">Промени</translation> +<translation id="8441146129660941386">Премотај уназад</translation> <translation id="8447861592752582886">Опозови дозволу за уређај</translation> <translation id="8463851957836045671">Сајт је брз</translation> <translation id="851751545965956758">Онемогући сајтовима да се повезују са уређајима</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Блокирајте колачиће за одређени сајт.</translation> <translation id="8959122750345127698">Навигација је недоступна: <ph name="URL" /></translation> <translation id="9019902583201351841">Овим управљају твоји родитељи</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Приступ микрофону</translation> <translation id="965817943346481315">Блокирај ако сајт приказује огласе који ометају активности или обмањујуће огласе (препоручено)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_sv.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_sv.xtb index 3fee51d6e98..9a7b370a96f 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_sv.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_sv.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Nästa</translation> <translation id="1242008676835033345">Inbäddad på <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Stopp</translation> +<translation id="1289742167380433257">Bilderna på den här sidan har optimerats av Google så att du sparar data.</translation> <translation id="129382876167171263">Filer som webbplatser har sparat visas här</translation> <translation id="1364532808393826295"><ph name="APP_NAME" />–<ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Webbplatsen <ph name="SITE_NAME" /> har lagts till</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Fråga innan webbplatser tillåts att skapa en 3D-karta över dina omgivningar eller registrera kamerans position (rekommenderas)</translation> <translation id="2212565012507486665">Tillåt cookies</translation> <translation id="2289270750774289114">Fråga när en webbplats försöker söka efter Bluetooth-enheter i närheten (rekommenderas)</translation> +<translation id="2315043854645842844">Val av certifikat på klienten stöds inte av operativsystemet.</translation> <translation id="2359808026110333948">Fortsätt</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">Nedladdningen är klar<ph name="SEPARATOR" /><ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Kopierat</translation> <translation id="2822354292072154809">Vill du återställa alla webbplatsbehörigheter för <ph name="CHOSEN_OBJECT_NAME" />?</translation> <translation id="2870560284913253234">Webbplats</translation> +<translation id="2874939134665556319">Föregående spår</translation> <translation id="2910701580606108292">Fråga innan webbplatser tillåts att spela upp skyddat innehåll</translation> <translation id="2913331724188855103">Tillåt att webbplatser sparar och läser cookiedata (rekommenderas)</translation> <translation id="2968755619301702150">Certifikatvisare</translation> <translation id="300526633675317032">Det här alternativet tar bort alla <ph name="SIZE_IN_KB" /> webbplatslagring.</translation> +<translation id="301521992641321250">Blockerades automatiskt</translation> <translation id="3115898365077584848">Visa info</translation> <translation id="3123473560110926937">Blockeras på vissa webbplatser</translation> <translation id="3190152372525844641">Aktivera behörigheter för Chrome i <ph name="BEGIN_LINK" />Android-inställningar<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Synkronisera i bakgrunden</translation> <translation id="3822502789641063741">Rensa webbplatslagring?</translation> <translation id="385051799172605136">Föregående</translation> +<translation id="3859306556332390985">Sök framåt</translation> <translation id="3955193568934677022">Tillåt att skyddat innehåll spelas upp på webbplatser (rekommenderas)</translation> <translation id="3987993985790029246">Kopiera länk</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> <translation id="4002066346123236978">Titel</translation> <translation id="4008040567710660924">Tillåt cookies för en enskild webbplats.</translation> +<translation id="4046123991198612571">Nästa spår</translation> <translation id="4165986682804962316">Platsinställningar</translation> <translation id="4226663524361240545">Aviseringar kan göra att enheten vibrerar</translation> <translation id="4242533952199664413">Öppna Inställningar</translation> <translation id="4259722352634471385">Webbadressen har blockerats: <ph name="URL" /></translation> <translation id="4278390842282768270">Tillåts</translation> +<translation id="429312253194641664">Media spelas upp på en webbplats</translation> <translation id="4433925000917964731">Lite-sida tillhandahållen av Google</translation> <translation id="4434045419905280838">Popup och omdirigeringar</translation> <translation id="445467742685312942">Tillåt att webbplatser spelar upp skyddat innehåll</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Återkalla alla behörigheter för enheten</translation> <translation id="4964199952259983386">Om du vill att Chrome ska använda AR måste du även aktivera kameran i <ph name="BEGIN_LINK" />inställningarna för Android<ph name="END_LINK" />.</translation> <translation id="497421865427891073">Fortsätt</translation> +<translation id="4996978546172906250">Dela via</translation> <translation id="5039804452771397117">Tillåt</translation> <translation id="5048398596102334565">Tillåt webbplatser att använda enhetens rörelsesensorer (rekommenderas)</translation> <translation id="5063480226653192405">Användning</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Rensa</translation> <translation id="6697925417670533197">Pågående nedladdningar</translation> <translation id="6746124502594467657">Flytta ned</translation> +<translation id="6766622839693428701">Svep nedåt när du vill stänga.</translation> <translation id="6782111308708962316">Hindra att webbplatser från tredje part sparar och läser cookiedata</translation> +<translation id="6790428901817661496">Spela</translation> <translation id="6818926723028410516">Välj objekt</translation> <translation id="6864395892908308021">Enheten kan inte läsa NFC</translation> <translation id="6910211073230771657">Borttagen</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">En webbplats använder kameran</translation> <translation id="7817023149356982970">Du loggas ut från webbplatsen.</translation> <translation id="7828557259026017104">Cookies är filer som har skapats av webbplatser du besöker. De används för att spara inställningar på en webbplats. Cookies från tredje part skapas av andra webbplatser. Dessa webbplatser äger en del av innehållet som visas på webbplatsen du besöker, till exempel annonser eller bilder.</translation> +<translation id="7835852323729233924">Spelar upp media</translation> <translation id="7846076177841592234">Rensa val</translation> <translation id="7846621471902887024">Du loggas ut från alla webbplatser.</translation> <translation id="7882806643839505685">Tillåt ljud för en webbplats.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Vill du ta bort all lokal data för webbplatsen, inklusive cookies, och återställa alla behörigheter för den?</translation> <translation id="8007176423574883786">Inaktiverad för den här enheten</translation> <translation id="802154636333426148">Nedladdningen misslyckades</translation> +<translation id="8068648041423924542">Det går inte att välja certifikat.</translation> <translation id="8087000398470557479">Innehållet kommer från <ph name="DOMAIN_NAME" /> via Google.</translation> <translation id="8116925261070264013">Ljudet avstängt</translation> <translation id="8131740175452115882">Bekräfta</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">En webbplats använder kameran och mikrofonen</translation> <translation id="8380167699614421159">Påträngande eller vilseledande annonser visas på den här webbplatsen</translation> <translation id="8394832520002899662">Återgå till webbplatsen genom att trycka här</translation> +<translation id="8425213833346101688">Ändra</translation> +<translation id="8441146129660941386">Sök bakåt</translation> <translation id="8447861592752582886">Återkalla enhetsbehörighet</translation> <translation id="8463851957836045671">Webbplatsen är snabb</translation> <translation id="851751545965956758">Förhindra att webbplatser ansluter till enheter</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Blockera cookies för en enskild webbplats.</translation> <translation id="8959122750345127698">Det går inte att nå webbadressen: <ph name="URL" /></translation> <translation id="9019902583201351841">Hanteras av dina föräldrar</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Tillgång till din mikrofon</translation> <translation id="965817943346481315">Blockera om påträngande eller vilseledande annonser visas på webbplatsen (rekommenderas)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_sw.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_sw.xtb index e177f012180..6e395feecee 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_sw.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_sw.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Endelea</translation> <translation id="1242008676835033345">Imepachikwa kwenye <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Simamisha</translation> +<translation id="1289742167380433257">Ili uhifadhi data yako, picha kwenye ukurasa huu zimeboreshwa na Google.</translation> <translation id="129382876167171263">Faili zinazohifadhiwa na tovuti huonekana hapa</translation> <translation id="1364532808393826295"><ph name="APP_NAME" />, <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Tovuti <ph name="SITE_NAME" /> imeongezwa</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Uliza kabla ya kuruhusu tovuti zibuni ramani ya 3D ya mazingira yako au kufuatilia mkao wa kamera (inapendekezwa)</translation> <translation id="2212565012507486665">Ruhusu vidakuzi</translation> <translation id="2289270750774289114">Niulize wakati tovuti inataka kugundua vifaa vya Bluetooth vilivyo karibu (inapendekezwa)</translation> +<translation id="2315043854645842844">Uchaguzi wa cheti cha sehemu ya seva teja hautumiwi na mfumo wa uendeshaji.</translation> <translation id="2359808026110333948">Endelea</translation> <translation id="2402980924095424747">MB <ph name="MEGABYTES" /></translation> <translation id="2434158240863470628">Upakuaji umekamilika <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Imenakiliwa</translation> <translation id="2822354292072154809">Una uhakika ungependa kubadilisha ruhusa zote za tovuti ya <ph name="CHOSEN_OBJECT_NAME" />?</translation> <translation id="2870560284913253234">Tovuti</translation> +<translation id="2874939134665556319">Wimbo uliotangulia</translation> <translation id="2910701580606108292">Iulize kabla ya kuruhusu tovuti kucheza maudhui yanayolindwa</translation> <translation id="2913331724188855103">Ruhusu tovuti zihifadhi na kusoma data ya vidakuzi (imependekezwa)</translation> <translation id="2968755619301702150">Kitazamaji vyeti</translation> <translation id="300526633675317032">Hatua hii itafuta <ph name="SIZE_IN_KB" /> yote ya hifadhi ya tovuti.</translation> +<translation id="301521992641321250">Imezuiwa kiotomatiki</translation> <translation id="3115898365077584848">Onyesha Maelezo</translation> <translation id="3123473560110926937">Yamezuiwa kwenye baadhi ya tovuti</translation> <translation id="3190152372525844641">Washa ruhusa za Chrome katika <ph name="BEGIN_LINK" />Mipangilio ya Android<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Usawazishaji wa chini chini</translation> <translation id="3822502789641063741">Ungependa kufuta hifadhi ya tovuti?</translation> <translation id="385051799172605136">Rudi nyuma</translation> +<translation id="3859306556332390985">Peleka mbele</translation> <translation id="3955193568934677022">Ruhusu tovuti zicheze maudhui yanayolindwa (inapendekezwa)</translation> <translation id="3987993985790029246">Nakili kiungo</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">Kichwa</translation> <translation id="4008040567710660924">Ruhusu vidakuzi katika tovuti maalum.</translation> +<translation id="4046123991198612571">Wimbo unaofuata</translation> <translation id="4165986682804962316">Mipangilio ya tovuti</translation> <translation id="4226663524361240545">Arifa huenda zitatetemesha kifaa</translation> <translation id="4242533952199664413">Fungua mipangilio</translation> <translation id="4259722352634471385">Kudurusu kumezuiwa: <ph name="URL" /></translation> <translation id="4278390842282768270">Imeruhusiwa</translation> +<translation id="429312253194641664">Tovuti inacheza maudhui</translation> <translation id="4433925000917964731">Ukurasa mwepesi umetolewa na Google</translation> <translation id="4434045419905280838">Madirisha ibukizi/kuelekeza kwingine</translation> <translation id="445467742685312942">Ruhusu tovuti icheze maudhui yanayolindwa</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Batilisha ruhusa zote za kifaa</translation> <translation id="4964199952259983386">Ili uruhusu Chome itumie Uhalisia Ulioboreshwa, washa pia kamera katika <ph name="BEGIN_LINK" />Mipangilio ya Android<ph name="END_LINK" />.</translation> <translation id="497421865427891073">Nenda mbele</translation> +<translation id="4996978546172906250">Shiriki kupitia</translation> <translation id="5039804452771397117">Ruhusu</translation> <translation id="5048398596102334565">Ruhusu tovuti zifikie vitambuzi vyako vya mwendo (inapendekezwa)</translation> <translation id="5063480226653192405">Matumizi</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Futa</translation> <translation id="6697925417670533197">Faili zinazopakuliwa</translation> <translation id="6746124502594467657">Songa chini</translation> +<translation id="6766622839693428701">Telezesha chini ili ufunge.</translation> <translation id="6782111308708962316">Zuia tovuti nyingine kuhifadhi na kusoma data ya vidakuzi</translation> +<translation id="6790428901817661496">Cheza</translation> <translation id="6818926723028410516">Chagua vipengee</translation> <translation id="6864395892908308021">Kifaa hiki kimeshindwa kusoma NFC</translation> <translation id="6910211073230771657">Imeondolewa</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Tovuti inatumia kamera yako</translation> <translation id="7817023149356982970">Utaondolewa kwenye akaunti ya tovuti hii.</translation> <translation id="7828557259026017104">Vidakuzi ni faili zinazoundwa na tovuti unazotembelea. Tovuti huvitumia kukumbuka mapendeleo yako. Vidakuzi vya washirika wengine hutengenezwa na tovuti nyingine. Tovuti hizo humiliki baadhi ya maudhui kama vile matangazo au picha ambazo unaona kwenye kurasa za wavuti unazotembelea.</translation> +<translation id="7835852323729233924">Kucheza maudhui</translation> <translation id="7846076177841592234">Ghairi uchaguzi</translation> <translation id="7846621471902887024">Utaondolewa kwenye akaunti za tovuti zote.</translation> <translation id="7882806643839505685">Ruhusu sauti katika tovuti mahususi.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Una uhakika unataka kufuta data zote za ndani, ikiwemo vidakuzi, na kuweka upya ruhusa za tovuti hii?</translation> <translation id="8007176423574883786">Imezimwa kwa kifaa hiki</translation> <translation id="802154636333426148">Haikuweza kupakua</translation> +<translation id="8068648041423924542">Imeshindwa kuchagua cheti.</translation> <translation id="8087000398470557479">Maudhui haya yanatoka <ph name="DOMAIN_NAME" />, yamewasilishwa na Google.</translation> <translation id="8116925261070264013">Imezimwa</translation> <translation id="8131740175452115882">Thibitisha</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Tovuti inatumia kamera na maikrofoni yako</translation> <translation id="8380167699614421159">Tovuti hii inaonyesha matangazo yanayopotosha au yanayokatiza huduma</translation> <translation id="8394832520002899662">Gusa ili urudi kwenye tovuti</translation> +<translation id="8425213833346101688">Badilisha</translation> +<translation id="8441146129660941386">Peleka nyuma</translation> <translation id="8447861592752582886">Batilisha ruhusa ya kifaa</translation> <translation id="8463851957836045671">Tovuti inapakia haraka</translation> <translation id="851751545965956758">Zuia tovuti zisiunganishe kwenye vifaa</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Zuia vidakuzi katika tovuti maalum.</translation> <translation id="8959122750345127698">Kudurusu hakufikiki: <ph name="URL" /></translation> <translation id="9019902583201351841">Inadhibitiwa na wazazi wako</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Kufikia maikrofoni yako</translation> <translation id="965817943346481315">Zuia ikiwa tovuti inaonyesha matangazo yanayopotosha au yanayokatiza huduma (inapendekezwa)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ta.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ta.xtb index be81d24e2c7..eec69344951 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ta.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ta.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">அடுத்து</translation> <translation id="1242008676835033345"><ph name="WEBSITE_URL" /> இல் உட்பொதியப்பட்டது</translation> <translation id="1272079795634619415">நிறுத்து</translation> +<translation id="1289742167380433257">உங்கள் டேட்டாவைச் சேமிப்பதற்காக, இந்தப் பக்கத்தின் படங்கள் Googleளால் சுருக்கப்பட்டுள்ளன.</translation> <translation id="129382876167171263">இணையதளங்கள் சேமித்த கோப்புகள் இங்கே தோன்றும்</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> - <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676"><ph name="SITE_NAME" /> தளம் சேர்க்கப்பட்டது</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">உங்களைச் சுற்றியுள்ள இடங்களின் 3D மேப்பை உருவாக்கவோ கேமரா நிலையை டிராக் செய்யவோ தளங்களை அனுமதிப்பதற்கு முன்பாக அனுமதி கேட்கும் (பரிந்துரைக்கப்படுகிறது)</translation> <translation id="2212565012507486665">குக்கீகளை அனுமதி</translation> <translation id="2289270750774289114">அருகிலுள்ள புளூடூத் சாதனங்களை வலைதளம் கண்டறிய முயலும்போது கேள் (பரிந்துரைக்கப்படுகிறது)</translation> +<translation id="2315043854645842844">கிளையன்ட் சார்பாக சான்றிதழ் தேர்ந்தெடுப்பை ஆப்ரேட்டிங் சிஸ்டம் ஆதரிக்கவில்லை.</translation> <translation id="2359808026110333948">தொடர்க</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> மெ.பை.</translation> <translation id="2434158240863470628">பதிவிறக்கம் முடிந்தது <ph name="SEPARATOR" /><ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">நகலெடுக்கப்பட்டது</translation> <translation id="2822354292072154809"><ph name="CHOSEN_OBJECT_NAME" />க்கான தள அனுமதிகள் அனைத்தையும் நிச்சயமாக மீட்டமைக்க விரும்புகிறீர்களா?</translation> <translation id="2870560284913253234">தளம்</translation> +<translation id="2874939134665556319">முந்தைய டிராக்</translation> <translation id="2910701580606108292">பாதுகாக்கப்பட்ட உள்ளடக்கத்தை இயக்குவதற்குத் தளங்களை அனுமதிக்கும் முன்பு அனுமதி கோரும்</translation> <translation id="2913331724188855103">குக்கீத் தரவை, தளங்கள் சேமிக்கவும் படிக்கவும் அனுமதி (பரிந்துரைக்கப்பட்டது)</translation> <translation id="2968755619301702150">சான்றிதழ் வியூவர்</translation> <translation id="300526633675317032">இணையதளச் சேமிப்பகத்தில் உள்ள <ph name="SIZE_IN_KB" /> தரவையும் இது அழிக்கும்.</translation> +<translation id="301521992641321250">தானாகத் தடுக்கப்பட்டது</translation> <translation id="3115898365077584848">தகவலைக் காட்டு</translation> <translation id="3123473560110926937">சில தளங்களில் தடுக்கப்பட்டுள்ளன</translation> <translation id="3190152372525844641"><ph name="BEGIN_LINK" />Android அமைப்புகளில்<ph name="END_LINK" /> Chromeக்கான அனுமதிகளை இயக்கவும்.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">பின்புல ஒத்திசைவு</translation> <translation id="3822502789641063741">தளச் சேமிப்பகத்தை அழிக்கவா?</translation> <translation id="385051799172605136">திரும்பு</translation> +<translation id="3859306556332390985">முன்செல்</translation> <translation id="3955193568934677022">பாதுகாக்கப்பட்ட உள்ளடக்கத்தை இயக்க, தளங்களை அனுமதி (பரிந்துரைக்கப்படுகிறது)</translation> <translation id="3987993985790029246">இணைப்பை நகலெடு</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">தலைப்பு</translation> <translation id="4008040567710660924">குறிப்பிட்ட தளத்திற்கு, குக்கீகளை அனுமதிக்கும்.</translation> +<translation id="4046123991198612571">அடுத்த டிராக்</translation> <translation id="4165986682804962316">தள அமைப்புகள்</translation> <translation id="4226663524361240545">அறிவிப்புகள் வரும் போது சாதனம் அதிர்வுறக்கூடும்</translation> <translation id="4242533952199664413">அமைப்புகளைத் திற</translation> <translation id="4259722352634471385">செல்வது தடுக்கப்பட்டது: <ph name="URL" /></translation> <translation id="4278390842282768270">அனுமதிக்கப்பட்டது</translation> +<translation id="429312253194641664">ஒரு தளம் மீடியாவை இயக்குகிறது</translation> <translation id="4433925000917964731">Google வழங்கும் Lite பக்கம்</translation> <translation id="4434045419905280838">பாப்-அப்கள் & திசைதிருப்புதல்கள்</translation> <translation id="445467742685312942">பாதுகாக்கப்பட்ட உள்ளடக்கத்தை இயக்குவதற்குத் தளங்களை அனுமதிக்கும்</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">சாதனத்திற்கான அனைத்து அனுமதிகளையும் ரத்துசெய்யும்</translation> <translation id="4964199952259983386">ARரைப் பயன்படுத்த Chromeமை அனுமதிப்பதற்கு, <ph name="BEGIN_LINK" />Android அமைப்புகளில்<ph name="END_LINK" /> கேமராவையும் இயக்கவும்.</translation> <translation id="497421865427891073">முன் செல்க</translation> +<translation id="4996978546172906250">இதன்வழியாக பகிர்</translation> <translation id="5039804452771397117">அனுமதி</translation> <translation id="5048398596102334565">மோஷன் சென்சார்களை அணுக தளங்களை அனுமதிக்கும் (பரிந்துரைக்கப்படுகிறது)</translation> <translation id="5063480226653192405">பயன்பாடு</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">அழி</translation> <translation id="6697925417670533197">செயலிலுள்ள பதிவிறக்கங்கள்</translation> <translation id="6746124502594467657">கீழே நகர்த்து</translation> +<translation id="6766622839693428701">மூடுவதற்கு, கீழே ஸ்வைப் செய்யவும்.</translation> <translation id="6782111308708962316">குக்கீத் தரவைச் சேமிப்பதிலிருந்தும் படிப்பதிலிருந்தும் மூன்றாம் தரப்பு இணையதளங்களைத் தடு</translation> +<translation id="6790428901817661496">இயக்கு</translation> <translation id="6818926723028410516">பட்டியலிலிருந்து தேர்ந்தெடுக்கவும்</translation> <translation id="6864395892908308021">இந்தச் சாதனத்தில் NFC ஆதரிக்கப்படவில்லை</translation> <translation id="6910211073230771657">நீக்கப்பட்டது</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">ஒரு தளம் உங்கள் கேமராவைப் பயன்படுத்துகிறது</translation> <translation id="7817023149356982970">இந்தத் தளத்தில் இருந்து வெளியேற்றப்படுவீர்கள்.</translation> <translation id="7828557259026017104">நீங்கள் பார்வையிடும் தளங்களால் உருவாக்கப்பட்ட கோப்புகளே குக்கீகள். உங்கள் விருப்பங்களை நினைவில் வைத்துக்கொள்ள இணையதளங்கள் இவற்றைப் பயன்படுத்துகின்றன. பிற தளங்களால் மூன்றாம் தரப்புக் குக்கீகள் உருவாக்கப்படுகின்றன. நீங்கள் பார்வையிடும் இணையப் பக்கத்தில் தோன்றக்கூடிய விளம்பரங்கள், படங்கள் போன்ற சில உள்ளடக்கங்கள் இந்தத் தளங்களுடையவையாக இருக்கும்.</translation> +<translation id="7835852323729233924">மீடியாவைப் பிளே செய்கிறது</translation> <translation id="7846076177841592234">தேர்வை ரத்துசெய்</translation> <translation id="7846621471902887024">அனைத்துத் தளங்களிலிருந்தும் வெளியேற்றப்படுவீர்கள்.</translation> <translation id="7882806643839505685">குறிப்பிட்ட தளத்திற்கு ஒலியை அனுமதி</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">இந்த இணையதளத்தின் குக்கீகள் உட்பட எல்லா அகத் தரவையும் அழித்து, அதன் எல்லா அனுமதிகளையும் மீட்டமைக்கவா?</translation> <translation id="8007176423574883786">இந்தச் சாதனத்திற்கு முடக்கப்பட்டுள்ளது</translation> <translation id="802154636333426148">பதிவிறக்க முடியவில்லை</translation> +<translation id="8068648041423924542">சான்றிதழைத் தேர்ந்தெடுக்க முடியவில்லை.</translation> <translation id="8087000398470557479">இந்த உள்ளடக்கம் <ph name="DOMAIN_NAME" /> (Google ஆல் வழங்கப்படுவது) இலிருந்து கிடைக்கிறது.</translation> <translation id="8116925261070264013">ஒலியடக்கியவை</translation> <translation id="8131740175452115882">உறுதிப்படுத்து</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">ஒரு தளம் உங்கள் மைக்ரோஃபோனையும் கேமராவையும் பயன்படுத்துகிறது</translation> <translation id="8380167699614421159">குறுக்கிடும் அல்லது தவறாக வழிநடத்தும் விளம்பரங்களை இந்தத் தளம் காண்பிக்கிறது</translation> <translation id="8394832520002899662">தளத்திற்குச் செல்ல, தட்டவும்</translation> +<translation id="8425213833346101688">மாற்று</translation> +<translation id="8441146129660941386">பின்செல்</translation> <translation id="8447861592752582886">சாதன அனுமதியை ரத்துசெய்யும்</translation> <translation id="8463851957836045671">தளம் வேகமாக இருக்கிறது</translation> <translation id="851751545965956758">சாதனங்களை இணைப்பதிலிருந்து தளங்களைத் தடுக்கும்</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">குறிப்பிட்ட தளத்திற்கான குக்கீகளைத் தடுக்கும்.</translation> <translation id="8959122750345127698">செல்ல முடியவில்லை: <ph name="URL" /></translation> <translation id="9019902583201351841">உங்கள் பெற்றோரால் நிர்வகிக்கப்படுகிறது</translation> +<translation id="9074739597929991885">புளூடூத்</translation> <translation id="945632385593298557">உங்கள் மைக்ரோஃபோனை அணுகலாம்</translation> <translation id="965817943346481315">குறுக்கிடும் அல்லது தவறாக வழிநடத்தும் விளம்பரங்களை தளம் காண்பித்தால், அதைத் தடு (பரிந்துரைக்கப்படுவது)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_te.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_te.xtb index 6db82f2c272..8b6e2e82461 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_te.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_te.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">తరువాత</translation> <translation id="1242008676835033345"><ph name="WEBSITE_URL" />లో పొందుపరచబడింది</translation> <translation id="1272079795634619415">ఆపు</translation> +<translation id="1289742167380433257">మీ కోసం డేటాను సేవ్ చేయడానికి, ఈ పేజీ ఇమేజ్లు Google ద్వారా ఆప్టిమైజ్ చేయబడ్డాయి.</translation> <translation id="129382876167171263">వెబ్సైట్లు సేవ్ చేసిన ఫైల్లు ఇక్కడ కనిపిస్తాయి</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> - <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676"><ph name="SITE_NAME" /> సైట్ జోడించబడింది</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">మీ పరిసరాల 3D మ్యాప్ను రూపొందించడానికి లేదా కెమెరా పొజిషన్ను ట్రాక్ చేయడానికి సైట్లను అనుమతించే ముందు అడగాలి (సిఫార్సు చేయడమైనది)</translation> <translation id="2212565012507486665">కుక్కీలను అనుమతించు</translation> <translation id="2289270750774289114">ఏదైనా ఒక సైట్ సమీపంలోని బ్లూటూత్ పరికరాలను కనుగొనాలనుకున్నప్పుడు అనుమతి అడుగుతుంది (సిఫార్సు చేయడమైనది)</translation> +<translation id="2315043854645842844">క్లయింట్ తరపు సర్టిఫికెట్ ఎంపికకు ఆపరేటింగ్ సిస్టమ్ మద్దతు లేదు.</translation> <translation id="2359808026110333948">కొనసాగించు</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">డౌన్లోడ్ పూర్తయింది <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">కాపీ చేయబడింది</translation> <translation id="2822354292072154809">మీరు <ph name="CHOSEN_OBJECT_NAME" /> కోసం అన్ని సైట్ అనుమతులను ఖచ్చితంగా రీసెట్ చేయాలనుకుంటున్నారా ?</translation> <translation id="2870560284913253234">సైట్</translation> +<translation id="2874939134665556319">మునుపటి ట్రాక్</translation> <translation id="2910701580606108292">సైట్లు రక్షిత కంటెంట్ను ప్లే చేయడానికి ముందు అనుమతి కోసం అడుగుతాయి</translation> <translation id="2913331724188855103">కుక్కీ డేటాను సేవ్ చేయడానికి, చదవడానికి సైట్లను అనుమతిస్తుంది (సిఫార్సు చేయబడింది)</translation> <translation id="2968755619301702150">ప్రమాణపత్రం వ్యూయర్</translation> <translation id="300526633675317032">ఇది వెబ్సైట్ నిల్వలోని మొత్తం <ph name="SIZE_IN_KB" />ను తీసివేస్తుంది.</translation> +<translation id="301521992641321250">స్వయంచాలకంగా బ్లాక్ చేయబడింది</translation> <translation id="3115898365077584848">సమాచారాన్ని చూపు</translation> <translation id="3123473560110926937">కొన్ని సైట్లలో బ్లాక్ చేయబడింది</translation> <translation id="3190152372525844641"><ph name="BEGIN_LINK" />Android సెట్టింగ్లు<ph name="END_LINK" />లో Chrome కోసం అనుమతులను ఆన్ చేయండి.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">బ్యాక్గ్రౌండ్ సింక్</translation> <translation id="3822502789641063741">సైట్ నిల్వను తీసివేయాలా?</translation> <translation id="385051799172605136">వెనుకకు</translation> +<translation id="3859306556332390985">ముందుకు జరుపు</translation> <translation id="3955193568934677022">రక్షిత కంటెంట్ను ప్లే చేయడానికి సైట్లను అనుమతిస్తుంది (సిఫార్సు చేయబడింది)</translation> <translation id="3987993985790029246">లింక్ను కాపీ చేయి</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">శీర్షిక</translation> <translation id="4008040567710660924">నిర్దిష్ట సైట్ కోసం కుక్కీలను అనుమతించండి.</translation> +<translation id="4046123991198612571">తరువాత ట్రాక్</translation> <translation id="4165986682804962316">సైట్ సెట్టింగ్లు</translation> <translation id="4226663524361240545">నోటిఫికేషన్లు పరికరాన్ని వైబ్రేట్ చేయవచ్చు</translation> <translation id="4242533952199664413">సెట్టింగ్లను తెరువు</translation> <translation id="4259722352634471385">నావిగేషన్ బ్లాక్ చేయబడింది: <ph name="URL" /></translation> <translation id="4278390842282768270">అనుమతించబడింది</translation> +<translation id="429312253194641664">ఒక సైట్లో మీడియా ప్లే చేయబడుతోంది</translation> <translation id="4433925000917964731">Google అందించిన లైట్ పేజీ</translation> <translation id="4434045419905280838">పాప్-అప్లు మరియు మళ్లింపులు</translation> <translation id="445467742685312942">రక్షిత కంటెంట్ను ప్లే చేయడానికి సైట్లను అనుమతిస్తుంది</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">పరికరానికి అన్ని అనుమతులను ఉపసంహరించు</translation> <translation id="4964199952259983386">ARను Chrome ఉపయోగించడానికి వీలుగా, <ph name="BEGIN_LINK" />Android సెట్టింగ్ల<ph name="END_LINK" />లో కూడా కెమెరాను ఆన్ చేయండి.</translation> <translation id="497421865427891073">ముందుకు వెళ్ళు</translation> +<translation id="4996978546172906250">దీని ద్వారా భాగస్వామ్యం చే.</translation> <translation id="5039804452771397117">అనుమతించు</translation> <translation id="5048398596102334565">మోషన్ సెన్సార్లను యాక్సెస్ చేయడానికి సైట్లను అనుమతించండి (సిఫార్సు చేస్తున్నాము)</translation> <translation id="5063480226653192405">నిల్వ వినియోగం</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">క్లియర్ చేయి</translation> <translation id="6697925417670533197">యాక్టివ్గా ఉన్న డౌన్లోడ్లు</translation> <translation id="6746124502594467657">క్రిందికి తరలించు</translation> +<translation id="6766622839693428701">మూసివేయడానికి దిగువకు స్వైప్ చేయండి.</translation> <translation id="6782111308708962316">మూడవ పక్షం వెబ్సైట్లను కుక్కీ డేటా సేవ్ చేయనీయకుండా, చదవనీయకుండా నిరోధించు</translation> +<translation id="6790428901817661496">ప్లే చేయి</translation> <translation id="6818926723028410516">అంశాలను ఎంచుకోండి</translation> <translation id="6864395892908308021">ఈ పరికరం NFCని రీడ్ చేయదు</translation> <translation id="6910211073230771657">తొలగించబడింది</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">ఒక సైట్ మీ కెమెరాను ఉపయోగిస్తోంది</translation> <translation id="7817023149356982970">మీరు ఈ సైట్ నుండి సైన్ అవుట్ చేయబడతారు.</translation> <translation id="7828557259026017104">మీరు సందర్శించే వెబ్సైట్లు రూపొందించిన ఫైల్లను కుక్కీలు అంటారు. మీ ప్రాధాన్యతలను గుర్తుంచుకోవడానికి సైట్లు వాటిని ఉపయోగిస్తాయి. ఇతర సైట్లు రూపొందించిన కుక్కీలను థర్డ్-పార్టీ కుక్కీలు అంటారు. మీరు సందర్శించే వెబ్ పేజీలో మీరు చూసే యాడ్లు లేదా ఇమేజ్ల లాంటి, కొంత కంటెంట్ను ఈ సైట్లు స్వంతంగా కలిగి ఉంటాయి.</translation> +<translation id="7835852323729233924">మీడియా ప్లే అవుతోంది</translation> <translation id="7846076177841592234">ఎంపికను రద్దు చేయి</translation> <translation id="7846621471902887024">మీరు అన్ని సైట్ల నుండి సైన్ అవుట్ చేయబడతారు.</translation> <translation id="7882806643839505685">నిర్దిష్ట సైట్ కోసం ధ్వనిని అనుమతించండి.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">కుక్కీలతో సహా, మొత్తం స్థానిక డేటాను తీసివేసి, ఈ వెబ్సైట్కు ఇచ్చిన అన్ని అనుమతులను రీసెట్ చేయాలని మీరు ఖచ్చితంగా కోరుకుంటున్నారా?</translation> <translation id="8007176423574883786">ఈ పరికరం కోసం ఆఫ్ చేయబడింది</translation> <translation id="802154636333426148">డౌన్లోడ్ విఫలమైంది</translation> +<translation id="8068648041423924542">ప్రమాణపత్రం ఎంపిక చేయడం సాధ్యపడలేదు.</translation> <translation id="8087000398470557479">ఈ కంటెంట్ Google ద్వారా డెలివర్ చేయబడిన <ph name="DOMAIN_NAME" />లోనిది.</translation> <translation id="8116925261070264013">మ్యూట్ చేసినవి</translation> <translation id="8131740175452115882">నిర్ధారించు</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">ఒక సైట్ మీ కెమెరాను, మైక్రోఫోన్ను ఉపయోగిస్తోంది</translation> <translation id="8380167699614421159">ఈ సైట్ అనుచితమైన లేదా తప్పుదారి పట్టించే ప్రకటనలను చూపుతుంది</translation> <translation id="8394832520002899662">సైట్కు తిరిగి వెళ్లడానికి ట్యాప్ చేయండి</translation> +<translation id="8425213833346101688">మార్చు</translation> +<translation id="8441146129660941386">వెనుకకు జరుపు</translation> <translation id="8447861592752582886">పరికర అనుమతిని ఉపసంహరిస్తుంది</translation> <translation id="8463851957836045671">సైట్ వేగంగా లోడ్ అవుతుంది</translation> <translation id="851751545965956758">పరికరాలకు కనెక్ట్ కాకుండా సైట్లను బ్లాక్ చేస్తుంది</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">ఏదైనా ఒక నిర్దిష్ట సైట్లో కుక్కీలను బ్లాక్ చేయండి.</translation> <translation id="8959122750345127698">దీనికి నావిగేట్ చేయడం సాధ్యపడదు: <ph name="URL" /></translation> <translation id="9019902583201351841">మీ తల్లిదండ్రుల ద్వారా నిర్వహించబడుతోంది</translation> +<translation id="9074739597929991885">బ్లూటూత్</translation> <translation id="945632385593298557">మీ మైక్రోఫోన్ యాక్సెస్ అనుమతి</translation> <translation id="965817943346481315">సైట్ అనుచితమైన లేదా తప్పుదారి పట్టించే ప్రకటనలను చూపించినప్పుడు బ్లాక్ చేయి (సిఫార్సు చేయబడింది)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_th.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_th.xtb index 49e039dc3a9..357292959a9 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_th.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_th.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">ถัดไป</translation> <translation id="1242008676835033345">ฝังอยู่ใน <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">หยุด</translation> +<translation id="1289742167380433257">Google ได้เพิ่มประสิทธิภาพให้รูปภาพในหน้านี้เพื่อประหยัดอินเทอร์เน็ตมือถือ</translation> <translation id="129382876167171263">ไฟล์ที่เว็บไซต์บันทึกไว้จะปรากฏที่นี่</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> - <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">เพิ่มเว็บไซต์ <ph name="SITE_NAME" /> แล้ว</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">ถามก่อนที่จะอนุญาตให้เว็บไซต์สร้างแผนที่ 3 มิติของสิ่งที่อยู่รอบตัวคุณหรือติดตามตำแหน่งของกล้อง (แนะนำ)</translation> <translation id="2212565012507486665">อนุญาตคุกกี้</translation> <translation id="2289270750774289114">ถามเมื่อเว็บไซต์ต้องการค้นหาอุปกรณ์บลูทูธใกล้เคียง (แนะนำ)</translation> +<translation id="2315043854645842844">ระบบปฏิบัติการไม่สนับสนุนการเลือกใบรับรองฝั่งลูกค้า</translation> <translation id="2359808026110333948">ต่อไป</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">ดาวน์โหลดเสร็จสมบูรณ์ <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">คัดลอกแล้ว</translation> <translation id="2822354292072154809">แน่ใจไหมว่าต้องการรีเซ็ตสิทธิ์ทั้งหมดของเว็บไซต์สำหรับ <ph name="CHOSEN_OBJECT_NAME" /></translation> <translation id="2870560284913253234">เว็บไซต์</translation> +<translation id="2874939134665556319">แทร็กก่อนหน้า</translation> <translation id="2910701580606108292">ถามก่อนอนุญาตให้เว็บไซต์เล่นเนื้อหาที่ได้รับความคุ้มครอง</translation> <translation id="2913331724188855103">อนุญาตให้เว็บไซต์บันทึกและอ่านข้อมูลคุกกี้ (แนะนำ)</translation> <translation id="2968755619301702150">เครื่องมือดูใบรับรอง</translation> <translation id="300526633675317032">การดำเนินการนี้จะล้างพื้นที่เก็บข้อมูลเว็บไซต์ทั้ง <ph name="SIZE_IN_KB" /></translation> +<translation id="301521992641321250">ถูกบล็อกโดยอัตโนมัติ</translation> <translation id="3115898365077584848">แสดงข้อมูล</translation> <translation id="3123473560110926937">บล็อกในบางเว็บไซต์</translation> <translation id="3190152372525844641">เปิดการใช้สิทธิ์สำหรับ Chrome ใน<ph name="BEGIN_LINK" />การตั้งค่า Android<ph name="END_LINK" /></translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">ซิงค์ในแบ็กกราวด์</translation> <translation id="3822502789641063741">ล้างพื้นที่เก็บข้อมูลเว็บไซต์ไหม</translation> <translation id="385051799172605136">กลับ</translation> +<translation id="3859306556332390985">ไปข้างหน้า</translation> <translation id="3955193568934677022">อนุญาตให้เว็บไซต์เล่นเนื้อหาที่ได้รับความคุ้มครอง (แนะนำ)</translation> <translation id="3987993985790029246">คัดลอกลิงก์</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> <translation id="4002066346123236978">ชื่อ</translation> <translation id="4008040567710660924">อนุญาตคุกกี้ของเว็บไซต์ที่เจาะจง</translation> +<translation id="4046123991198612571">แทร็กถัดไป</translation> <translation id="4165986682804962316">การตั้งค่าเว็บไซต์</translation> <translation id="4226663524361240545">การแจ้งเตือนอาจทำให้อุปกรณ์สั่น</translation> <translation id="4242533952199664413">เปิดการตั้งค่า</translation> <translation id="4259722352634471385">มีการบล็อกการนำทาง: <ph name="URL" /></translation> <translation id="4278390842282768270">อนุญาตแล้ว</translation> +<translation id="429312253194641664">เว็บไซต์กำลังเล่นสื่อ</translation> <translation id="4433925000917964731">หน้าเวอร์ชัน Lite ให้บริการโดย Google</translation> <translation id="4434045419905280838">ป๊อปอัปและการเปลี่ยนเส้นทาง</translation> <translation id="445467742685312942">อนุญาตให้เว็บไซต์เล่นเนื้อหาที่ได้รับความคุ้มครอง</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">เพิกถอนสิทธิ์ทั้งหมดสำหรับอุปกรณ์</translation> <translation id="4964199952259983386">หากต้องการให้ Chrome ใช้ AR ให้เปิดกล้องใน<ph name="BEGIN_LINK" />การตั้งค่า Android<ph name="END_LINK" /> ด้วย</translation> <translation id="497421865427891073">ไปข้างหน้า</translation> +<translation id="4996978546172906250">แชร์ผ่าน</translation> <translation id="5039804452771397117">อนุญาต</translation> <translation id="5048398596102334565">อนุญาตให้เว็บไซต์เข้าถึงเซ็นเซอร์ตรวจจับความเคลื่อนไหว (แนะนำ)</translation> <translation id="5063480226653192405">การใช้</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">ล้าง</translation> <translation id="6697925417670533197">การดาวน์โหลดที่ทำงานอยู่</translation> <translation id="6746124502594467657">เลื่อนลง</translation> +<translation id="6766622839693428701">เลื่อนลงเพื่อปิด</translation> <translation id="6782111308708962316">ป้องกันไม่ให้เว็บไซต์ของบุคคลที่สามบันทึกและอ่านข้อมูลคุกกี้</translation> +<translation id="6790428901817661496">เล่น</translation> <translation id="6818926723028410516">เลือกรายการ</translation> <translation id="6864395892908308021">อุปกรณ์นี้อ่าน NFC ไม่ได้</translation> <translation id="6910211073230771657">ลบแล้ว</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">มีเว็บไซต์กำลังใช้กล้อง</translation> <translation id="7817023149356982970">คุณจะออกจากระบบของเว็บไซต์นี้</translation> <translation id="7828557259026017104">คุกกี้คือไฟล์ที่เว็บไซต์ต่างๆ ที่คุณเข้าชมสร้างขึ้น เว็บไซต์ใช้คุกกี้เพื่อจดจำข้อมูลการท่องเว็บของคุณ คุกกี้ของบุคคลที่สามซึ่งเว็บไซต์อื่นๆ เป็นผู้สร้างขึ้น เว็บไซต์เหล่านี้เป็นเจ้าของเนื้อหาบางอย่าง เช่น โฆษณาหรือรูปภาพที่คุณเห็นในหน้าเว็บที่เข้าชม</translation> +<translation id="7835852323729233924">กำลังเล่นสื่อ</translation> <translation id="7846076177841592234">ยกเลิกการเลือก</translation> <translation id="7846621471902887024">คุณจะออกจากระบบของทุกเว็บไซต์</translation> <translation id="7882806643839505685">อนุญาตให้เว็บไซต์ที่ต้องการเล่นเสียงได้</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">คุณแน่ใจไหมว่าต้องการล้างข้อมูลในเครื่องทั้งหมด รวมถึงคุกกี้ และรีเซ็ตสิทธิ์ทั้งหมดสำหรับเว็บไซต์นี้</translation> <translation id="8007176423574883786">ปิดสำหรับอุปกรณ์นี้</translation> <translation id="802154636333426148">การดาวน์โหลดล้มเหลว</translation> +<translation id="8068648041423924542">เลือกใบรับรองไม่ได้</translation> <translation id="8087000398470557479">เนื้อหานี้มาจาก <ph name="DOMAIN_NAME" /> และนำส่งโดย Google</translation> <translation id="8116925261070264013">ปิดเสียง</translation> <translation id="8131740175452115882">ยืนยัน</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">มีเว็บไซต์กำลังใช้กล้องถ่ายรูปและไมโครโฟน</translation> <translation id="8380167699614421159">เว็บไซต์นี้แสดงโฆษณาที่แทรกหรือทำให้เข้าใจผิด</translation> <translation id="8394832520002899662">แตะเพื่อกลับไปที่เว็บไซต์</translation> +<translation id="8425213833346101688">เปลี่ยน</translation> +<translation id="8441146129660941386">ย้อนกลับ</translation> <translation id="8447861592752582886">เพิกถอนสิทธิ์ของอุปกรณ์</translation> <translation id="8463851957836045671">เว็บไซต์โหลดเร็ว</translation> <translation id="851751545965956758">บล็อกเว็บไซต์ไม่ให้เชื่อมต่อกับอุปกรณ์</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">บล็อกคุกกี้ของเว็บไซต์ที่เจาะจง</translation> <translation id="8959122750345127698">ไม่สามารถเข้าถึงการนำทางได้: <ph name="URL" /></translation> <translation id="9019902583201351841">มีการจัดการโดยผู้ปกครอง</translation> +<translation id="9074739597929991885">บลูทูธ</translation> <translation id="945632385593298557">เข้าถึงไมโครโฟน</translation> <translation id="965817943346481315">บล็อกหากเว็บไซต์แสดงโฆษณาที่แทรกหรือทำให้เข้าใจผิด (แนะนำ)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_tr.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_tr.xtb index cc5d9333a0c..f38b63a362f 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_tr.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_tr.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">İleri</translation> <translation id="1242008676835033345"><ph name="WEBSITE_URL" /> adresinde yerleşik</translation> <translation id="1272079795634619415">Durdur</translation> +<translation id="1289742167380433257">Veri tasarrufu amacıyla bu sayfadaki görseller Google tarafından optimize edilmiştir.</translation> <translation id="129382876167171263">Web siteleri tarafından kaydedilen dosyalar burada görünür</translation> <translation id="1364532808393826295"><ph name="APP_NAME" />-<ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676"><ph name="SITE_NAME" /> sitesi eklendi</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Sitelerin çevremin 3D haritasını oluşturmasına veya kamera konumunu takip etmesine izin vermeden önce sor (önerilir)</translation> <translation id="2212565012507486665">Çerezlere izin ver</translation> <translation id="2289270750774289114">Bir site yakındaki Bluetooth cihazları bulmak istediğinde sor (önerilir)</translation> +<translation id="2315043854645842844">İstemci tarafı sertifika seçimi, işletim sistemi tarafından desteklenmiyor.</translation> <translation id="2359808026110333948">Devam et</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">İndirme işlemi tamamlandı <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Kopyalandı</translation> <translation id="2822354292072154809"><ph name="CHOSEN_OBJECT_NAME" /> için tüm site izinlerini sıfırlamak istediğinizden emin misiniz?</translation> <translation id="2870560284913253234">Site</translation> +<translation id="2874939134665556319">Önceki parça</translation> <translation id="2910701580606108292">Sitelerin korumalı içeriği oynatmasına izin verilmeden önce size sorulur</translation> <translation id="2913331724188855103">Sitelerin, çerez verilerini kaydetmelerine ve okumalarına izin ver (önerilir)</translation> <translation id="2968755619301702150">Sertifika görüntüleyici</translation> <translation id="300526633675317032">Bu işlem <ph name="SIZE_IN_KB" /> olan web sitesi depolama alanının tamamını temizleyecek.</translation> +<translation id="301521992641321250">Otomatik olarak engellendi</translation> <translation id="3115898365077584848">Bilgileri Göster</translation> <translation id="3123473560110926937">Bazı sitelerde engellendi</translation> <translation id="3190152372525844641"><ph name="BEGIN_LINK" />Android Ayarları<ph name="END_LINK" />'nda Chrome için izinleri açın.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Arka plan senkronizasyonu</translation> <translation id="3822502789641063741">Site depolama silinsin mi?</translation> <translation id="385051799172605136">Geri</translation> +<translation id="3859306556332390985">İleriye doğru git</translation> <translation id="3955193568934677022">Sitelerin korumalı içeriği oynatmasına izin ver (önerilir)</translation> <translation id="3987993985790029246">Bağlantıyı kopyala</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">Başlık</translation> <translation id="4008040567710660924">Belirli bir site için çerezlere izin verin.</translation> +<translation id="4046123991198612571">Sonraki parça</translation> <translation id="4165986682804962316">Site ayarları</translation> <translation id="4226663524361240545">Bildirimler cihazı titretebilir</translation> <translation id="4242533952199664413">Ayarları aç</translation> <translation id="4259722352634471385">Gezinme engellendi: <ph name="URL" /></translation> <translation id="4278390842282768270">İzin verilen</translation> +<translation id="429312253194641664">Bir site medya oynatıyor</translation> <translation id="4433925000917964731">Google tarafından sağlanan basit sayfa</translation> <translation id="4434045419905280838">Pop-up'lar ve yönlendirmeler</translation> <translation id="445467742685312942">Sitelerin korumalı içeriği oynatmasına izin ver</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Cihaz için tüm izinleri iptal eder</translation> <translation id="4964199952259983386">Chrome'un artırılmış gerçekliği (AR) kullanması için <ph name="BEGIN_LINK" />Android Ayarlarında<ph name="END_LINK" /> kamerayı da açın.</translation> <translation id="497421865427891073">İlerle</translation> +<translation id="4996978546172906250">Paylaşım yöntemi:</translation> <translation id="5039804452771397117">İzin ver</translation> <translation id="5048398596102334565">Sitelerin hareket sensörlerine erişmesine izin ver (önerilen)</translation> <translation id="5063480226653192405">Kullanım</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Temizle</translation> <translation id="6697925417670533197">Etkin indirme işlemleri</translation> <translation id="6746124502594467657">Aşağı taşı</translation> +<translation id="6766622839693428701">Kapatmak için aşağı kaydırın.</translation> <translation id="6782111308708962316">Üçüncü taraf web sitelerinin çerez verilerini kaydetmesini ve okumasını engelle</translation> +<translation id="6790428901817661496">Oynat</translation> <translation id="6818926723028410516">Öğe seçin</translation> <translation id="6864395892908308021">Bu cihaz NFC'yi okuyamıyor</translation> <translation id="6910211073230771657">Silindi</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Bir site kameranızı kullanıyor</translation> <translation id="7817023149356982970">Bu sitedeki oturumunuz kapatılacak.</translation> <translation id="7828557259026017104">Çerezler, ziyaret ettiğiniz web siteleri tarafından oluşturulan dosyalardır. Siteler tercihlerinizi hatırlamak için çerezleri kullanır. Üçüncü taraf çerezleri diğer siteler tarafından oluşturulur. Bu siteler, ziyaret ettiğiniz web sayfasında gördüğünüz reklam veya resim gibi içeriğin bir kısmına sahiptir.</translation> +<translation id="7835852323729233924">Medya oynatılıyor/çalınıyor</translation> <translation id="7846076177841592234">Seçimi iptal et</translation> <translation id="7846621471902887024">Tüm sitelerdeki oturumunuz kapatılacak.</translation> <translation id="7882806643839505685">Belirli bir site için sese izin verin.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Bu web sitesine ilişkin çerezler dahil tüm yerel verileri temizlemek ve bu sitenin tüm izinlerini sıfırlamak istediğinizden emin misiniz?</translation> <translation id="8007176423574883786">Bu cihaz için kapatıldı</translation> <translation id="802154636333426148">İndirilemedi</translation> +<translation id="8068648041423924542">Sertifika seçilemiyor.</translation> <translation id="8087000398470557479">Bu içerik Google tarafından <ph name="DOMAIN_NAME" /> adresinden sağlanmaktadır.</translation> <translation id="8116925261070264013">Ses kapatıldı</translation> <translation id="8131740175452115882">Onayla</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Bir site kameranızı ve mikrofonunuzu kullanıyor</translation> <translation id="8380167699614421159">Bu site, araya giren veya yanıltıcı reklamlar gösteriyor</translation> <translation id="8394832520002899662">Siteye dönmek için dokunun</translation> +<translation id="8425213833346101688">Değiştir</translation> +<translation id="8441146129660941386">Geriye doğru git</translation> <translation id="8447861592752582886">Cihaz iznini iptal et</translation> <translation id="8463851957836045671">Site hızlı yükleniyor</translation> <translation id="851751545965956758">Sitelerin cihazlara bağlanmasını engelle</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Belirli bir site için çerezleri engelleyin.</translation> <translation id="8959122750345127698">Gezinme işlevine ulaşılamıyor: <ph name="URL" /></translation> <translation id="9019902583201351841">Ebeveynleriniz tarafından yönetiliyor</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Mikrofonunuza erişim</translation> <translation id="965817943346481315">Site, araya giren veya yanıltıcı reklamlar gösteriyorsa engelle (önerilen)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_uk.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_uk.xtb index fdfb5512501..d449f6d6177 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_uk.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_uk.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Далі</translation> <translation id="1242008676835033345">Вбудовано на сайті <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Зупинити</translation> +<translation id="1289742167380433257">Щоб заощадити трафік, ми оптимізували зображення на цій сторінці.</translation> <translation id="129382876167171263">Файли, збережені веб-сайтами, відображаються тут</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> – <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Сайт <ph name="SITE_NAME" /> додано</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Запитувати, перш ніж дозволяти сайтам створювати 3D-карту вашого оточення або відстежувати положення камери (рекомендовано)</translation> <translation id="2212565012507486665">Дозволити файли cookie</translation> <translation id="2289270750774289114">Запитувати, коли сайт хоче шукати пристрої Bluetooth поблизу (рекомендовано)</translation> +<translation id="2315043854645842844">Операційна система не підтримує сертифікат, вибраний на стороні клієнта.</translation> <translation id="2359808026110333948">Продовжити</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> МБ</translation> <translation id="2434158240863470628">Завантажено <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Скопійов.</translation> <translation id="2822354292072154809">Скинути всі дозволи сайту <ph name="CHOSEN_OBJECT_NAME" />?</translation> <translation id="2870560284913253234">Сайт</translation> +<translation id="2874939134665556319">Попередня композиція</translation> <translation id="2910701580606108292">Запитувати, перш ніж дозволяти сайтам відтворювати захищений вміст</translation> <translation id="2913331724188855103">Дозволити сайтам зберігати та розпізнавати дані файлів cookie (рекомендується)</translation> <translation id="2968755619301702150">Перегляд сертифікатів</translation> <translation id="300526633675317032">Буде видалено всі дані сайтів (<ph name="SIZE_IN_KB" />).</translation> +<translation id="301521992641321250">Блокується автоматично</translation> <translation id="3115898365077584848">Показати інформацію</translation> <translation id="3123473560110926937">Заблоковано на деяких сайтах</translation> <translation id="3190152372525844641">Увімкніть дозволи для Chrome у <ph name="BEGIN_LINK" />налаштуваннях Android<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Фонова синхронізація</translation> <translation id="3822502789641063741">Видалити дані сайтів?</translation> <translation id="385051799172605136">Назад</translation> +<translation id="3859306556332390985">Далі</translation> <translation id="3955193568934677022">Дозволити сайтам відтворювати захищений вміст (рекомендується)</translation> <translation id="3987993985790029246">Копіювати</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> <translation id="4002066346123236978">Назва</translation> <translation id="4008040567710660924">Дозволити файли cookie для конкретного сайту.</translation> +<translation id="4046123991198612571">Наступна композиція</translation> <translation id="4165986682804962316">Налаштування сайту</translation> <translation id="4226663524361240545">Коли надходитимуть сповіщення, пристрій може вібрувати</translation> <translation id="4242533952199664413">Відкрити налаштування</translation> <translation id="4259722352634471385">Веб-сторінку <ph name="URL" /> заблоковано</translation> <translation id="4278390842282768270">Дозволено</translation> +<translation id="429312253194641664">Сайт відтворює медіа-вміст</translation> <translation id="4433925000917964731">Спрощену сторінку надає Google</translation> <translation id="4434045419905280838">Спливаючі вікна й переадресація</translation> <translation id="445467742685312942">Дозволити сайтам відтворювати захищений вміст</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Скасувати всі дозволи для пристрою</translation> <translation id="4964199952259983386">Щоб дозволити Chrome використовувати доповнену реальність, увімкніть камеру в <ph name="BEGIN_LINK" />налаштуваннях Android<ph name="END_LINK" />.</translation> <translation id="497421865427891073">Перейти вперед</translation> +<translation id="4996978546172906250">Надіслати</translation> <translation id="5039804452771397117">Дозволити</translation> <translation id="5048398596102334565">Надати сайтам доступ до датчиків руху (рекомендовано)</translation> <translation id="5063480226653192405">Використання</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Очистити</translation> <translation id="6697925417670533197">Активні завантаження</translation> <translation id="6746124502594467657">Вниз</translation> +<translation id="6766622839693428701">Проведіть пальцем униз, щоб закрити.</translation> <translation id="6782111308708962316">Забороняти стороннім веб-сайтам зберігати та переглядати дані файлів cookie</translation> +<translation id="6790428901817661496">Відтворити</translation> <translation id="6818926723028410516">Виберіть елементи</translation> <translation id="6864395892908308021">Цей пристрій не підтримує NFC</translation> <translation id="6910211073230771657">Видалено</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Сайт використовує камеру</translation> <translation id="7817023149356982970">Ви вийдете з облікового запису на цьому сайті.</translation> <translation id="7828557259026017104">Файли cookie – це файли, створені веб-сайтами, які ви відвідали. Сайти використовують їх, щоб запам'ятовувати ваші налаштування. Сторонні файли cookie створюються іншими сайтами. Ці сайти показують власний контент, як-от оголошення чи зображення, на веб-сторінці, яку ви відвідуєте.</translation> +<translation id="7835852323729233924">Відтворення медіафайлу</translation> <translation id="7846076177841592234">Скасувати вибір</translation> <translation id="7846621471902887024">Ви вийдете з облікового запису на всіх сайтах.</translation> <translation id="7882806643839505685">Увімкнути звук для певного сайту.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Видалити всі локальні дані, зокрема файли cookie, і скинути всі дозволи для цього веб-сайту?</translation> <translation id="8007176423574883786">Вимкнено для цього пристрою</translation> <translation id="802154636333426148">Не вдалося завантажити</translation> +<translation id="8068648041423924542">Не вдалося вибрати сертифікат.</translation> <translation id="8087000398470557479">Це вміст із сайту <ph name="DOMAIN_NAME" />, який доставляє Google.</translation> <translation id="8116925261070264013">Звук вимкнено</translation> <translation id="8131740175452115882">Підтвердити</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Сайт використовує камеру та мікрофон</translation> <translation id="8380167699614421159">Цей сайт показує нав’язливі чи оманливі оголошення</translation> <translation id="8394832520002899662">Натисніть, щоб повернутися на сайт</translation> +<translation id="8425213833346101688">Змінити</translation> +<translation id="8441146129660941386">Назад</translation> <translation id="8447861592752582886">Скасувати доступ до пристрою</translation> <translation id="8463851957836045671">Сайт працює швидко</translation> <translation id="851751545965956758">Заборонити сайтам підключатися до пристроїв</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Блокувати файли cookie з конкретного сайту.</translation> <translation id="8959122750345127698">Веб-сторінка <ph name="URL" /> недоступна</translation> <translation id="9019902583201351841">Керується батьками</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Доступ до мікрофона</translation> <translation id="965817943346481315">Блокувати, якщо сайт показує нав’язливі чи оманливі оголошення (рекомендовано)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ur.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ur.xtb index afe83ed8f6f..564ff83471d 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ur.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_ur.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">اگلا</translation> <translation id="1242008676835033345"><ph name="WEBSITE_URL" /> پر سرایت کردہ</translation> <translation id="1272079795634619415">روکیں</translation> +<translation id="1289742167380433257">آپ کے ڈیٹا کو محفوظ کرنے کیلئے، اس صفحہ کی تصاویر Google کے ذریعے بہتر بنائی گئی ہیں۔</translation> <translation id="129382876167171263">ویب سائٹس کے ذریعے محفوظ کردہ فائلز یہاں ظاہر ہوں گی</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> - <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">سائٹ <ph name="SITE_NAME" /> شامل کی گئی</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">سائٹس کو اپنے اطراف کا 3D نقشہ تخلیق یا کیمرے کی پوزیشن ٹریک کرنے کی اجازت دینے سے پہلے پوچھیں (تجویز کردہ)</translation> <translation id="2212565012507486665">کوکیز کی اجازت دیں</translation> <translation id="2289270750774289114">اس وقت پوچھیں جب کسی سائٹ میں قریبی بلوٹوتھ آلات کو دریافت کرنا مقصود ہو (تجویز کردہ)</translation> +<translation id="2315043854645842844">کلائنٹ سائڈ سرٹیفکیٹ کا انتخاب آپریٹنگ سسٹم کے ذریعہ تعاون یافتہ نہیں ہے۔</translation> <translation id="2359808026110333948">جاری رکھیں</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">ڈاؤن لوڈ مکمل ہو گیا <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">کاپی کیا</translation> <translation id="2822354292072154809">کیا آپ واقعی <ph name="CHOSEN_OBJECT_NAME" /> کے لیے سائٹ کی سبھی اجازتوں کو دوبارہ ترتیب دینا چاہتے ہیں؟</translation> <translation id="2870560284913253234">سائٹ</translation> +<translation id="2874939134665556319">پچھلا ٹریک</translation> <translation id="2910701580606108292">سائٹس کو محفوظ مواد چلانے کی اجازت دینے سے پہلے پوچھیں</translation> <translation id="2913331724188855103">سائٹس کو کوکی ڈیٹا کو محفوظ کرنے اور پڑھنے کی اجازت دیں (تجویز کردہ)</translation> <translation id="2968755619301702150">سرٹیفیکیٹ ناظر</translation> <translation id="300526633675317032">اس سے ویب سائٹ اسٹوریج کا کُل <ph name="SIZE_IN_KB" /> صاف ہو جائے گا۔</translation> +<translation id="301521992641321250">خود کار طور پر مسدود ہو گيا</translation> <translation id="3115898365077584848">معلومات دکھائیں</translation> <translation id="3123473560110926937">بعض سائٹس پر مسدود ہے</translation> <translation id="3190152372525844641"><ph name="BEGIN_LINK" />Android ترتیبات<ph name="END_LINK" /> میں Chrome کیلئے اجازتیں آن کریں۔</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">پس منظر کی مطابقت پذیری</translation> <translation id="3822502789641063741">سائٹ کا اسٹوریج صاف کریں؟</translation> <translation id="385051799172605136">پیچھے</translation> +<translation id="3859306556332390985">آگے لے جائیں</translation> <translation id="3955193568934677022">سائٹس کو محفوظ کردہ مواد چلانے کی اجازت دیں (تجویز کردہ)</translation> <translation id="3987993985790029246">لنک کاپی کریں</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">عنوان</translation> <translation id="4008040567710660924">مخصوص سائٹ کے لیے کوکیز کی اجازت دیں۔</translation> +<translation id="4046123991198612571">اگلا ٹریک</translation> <translation id="4165986682804962316">سائٹ کی ترتیبات</translation> <translation id="4226663524361240545">اطلاعات آلہ کو وائبریٹ کر سکتی ہیں</translation> <translation id="4242533952199664413">ترتیبات کھولیں</translation> <translation id="4259722352634471385">نیویگیشن مسدود ہے: <ph name="URL" /></translation> <translation id="4278390842282768270">اجازت یافتہ</translation> +<translation id="429312253194641664">سائٹ پر میڈیا چل رہا ہے</translation> <translation id="4433925000917964731">Google کی طرف سے فراہم کردہ لائٹ صفحہ</translation> <translation id="4434045419905280838">پوپ اپس اور ری ڈائریکٹس</translation> <translation id="445467742685312942">سائٹس کو محفوظ مواد چلانے کی اجازت دیں</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">آلہ کے لیے سبھی اجازتوں کو کالعدم کریں</translation> <translation id="4964199952259983386">Chrome کو AR کا استعمال کرنے دینے کے لیے، <ph name="BEGIN_LINK" />Android ترتیبات<ph name="END_LINK" /> میں بھی کیمرا آن کریں۔</translation> <translation id="497421865427891073">آگے جائیں</translation> +<translation id="4996978546172906250">اشتراک کریں بذریعہ</translation> <translation id="5039804452771397117">اجازت دیں</translation> <translation id="5048398596102334565">سائٹس کو موشن سینسرز تک رسائی حاصل کرنے کی اجازت دیں (تجویز کردہ)</translation> <translation id="5063480226653192405">استعمال</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">صاف کریں</translation> <translation id="6697925417670533197">فعال ڈاؤن لوڈز</translation> <translation id="6746124502594467657">نیچے منتقل کریں</translation> +<translation id="6766622839693428701">بند کرنے کے لئے نیچے سوائپ کریں۔</translation> <translation id="6782111308708962316">فریق ثالث ویب سائٹس کو کوکی ڈیٹا محفوظ کرنے اور پڑھنے سے روکیں</translation> +<translation id="6790428901817661496">چلائیں</translation> <translation id="6818926723028410516">آئٹمز منتخب کریں</translation> <translation id="6864395892908308021">یہ آلہ NFC کو نہیں پڑھ سکتا</translation> <translation id="6910211073230771657">حذف کردہ</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">ایک سائٹ آپ کا کیمرا استعمال کر رہی ہے</translation> <translation id="7817023149356982970">ایک آپ اس سائٹ سے سائن آؤٹ ہو جائیں گے۔</translation> <translation id="7828557259026017104">کوکیز ایسی فائلز ہوتی ہیں جنہیں آپ کی ملاحظہ کی جانے والی ویب سائٹس تخلیق کرتی ہیں۔ سائٹس آپ کی ترجیحات کو یاد رکھنے کیلئے ان کا استعمال کرتی ہیں۔ فریق ثالث کوکیز دیگر سائٹس کے ذریعے تخلیق کی جاتی ہیں۔ یہ سائٹس کچھ مواد کی مالک ہوتی ہیں، جیسے اشتہارات یا تصاویر جنہیں آپ ملاحظہ کی جانے والی ویب صفحہ پر دیکھتے ہیں۔</translation> +<translation id="7835852323729233924">میڈیا کو چلایا جا رہا ہے</translation> <translation id="7846076177841592234">انتخاب منسوخ کریں</translation> <translation id="7846621471902887024">آپ سبھی سائٹس سے سائن آؤٹ ہو جائیں گے۔</translation> <translation id="7882806643839505685">کسی مخصوص سائٹ کیلئے آواز کی اجازت دیں۔</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">کیا آپ واقعی کوکیز سمیت سبھی مقامی ڈيٹا صاف کرنا اور اس ویب سائٹ کیلئے سبھی اجازتیں دوبارہ ترتیب دینا چاہتے ہیں؟</translation> <translation id="8007176423574883786">اس آلے کیلئے آف کر دیا گیا</translation> <translation id="802154636333426148">ڈاؤن لوڈ ناکام ہوگیا</translation> +<translation id="8068648041423924542">سرٹیفکیٹ منتخب کرنے سے قاصر ہے۔</translation> <translation id="8087000398470557479">یہ مواد <ph name="DOMAIN_NAME" /> کی جانب سے ہے، جسے Google نے ڈیلیور کیا ہے۔</translation> <translation id="8116925261070264013">خاموش کردہ</translation> <translation id="8131740175452115882">تصدیق کریں</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">ایک سائٹ آپ کا کیمرا اور مائیکروفون استعمال کر رہی ہے</translation> <translation id="8380167699614421159">یہ سائٹ دخل انداز یا گمراہ کن اشتہارات دکھاتی ہے</translation> <translation id="8394832520002899662">سائٹ پر واپس جانے کے لیے تھپتھپائیں</translation> +<translation id="8425213833346101688">تبدیل کریں</translation> +<translation id="8441146129660941386">پیچھے لے جائیں</translation> <translation id="8447861592752582886">آلہ کی اجازت کالعدم کریں</translation> <translation id="8463851957836045671">سائٹ تیز ہے</translation> <translation id="851751545965956758">سائٹس کو آلات سے منسلک ہونے سے مسدود کریں</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">کسی مخصوص سائٹ کے لیے کوکیز مسدود کریں۔</translation> <translation id="8959122750345127698">نیویگیشن ناقابل رسائی ہے: <ph name="URL" /></translation> <translation id="9019902583201351841">آپ کے والدین کے زیر انتظام</translation> +<translation id="9074739597929991885">بلوٹوتھ</translation> <translation id="945632385593298557">اپنے مائیکروفون تک رسائی حاصل کریں</translation> <translation id="965817943346481315">اگر سائٹ دخل انداز یا گمراہ کن اشتہارات دکھاتی ہے تو مسدود کریں (تجویز کردہ)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_uz.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_uz.xtb index 1bcb22ecb1e..989f9e8f569 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_uz.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_uz.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Keyingisi</translation> <translation id="1242008676835033345"><ph name="WEBSITE_URL" /> saytiga joylangan</translation> <translation id="1272079795634619415">To‘xtatish</translation> +<translation id="1289742167380433257">Trafikni tejash maqsadida sahifadagi rasmlar Google tomonidan takomillashtirildi.</translation> <translation id="129382876167171263">Saytlardan saqlangan fayllar shu yerda chiqadi</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> - <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676"><ph name="SITE_NAME" /> sayti qo‘shildi</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Saytlar atrofingiz 3D xaritasini yaratish yoki kamera holatini kuzatish oldin ruxsat olsin (tavsiya etiladi)</translation> <translation id="2212565012507486665">Cookie fayllariga ruxsat berish</translation> <translation id="2289270750774289114">Sayt atrofdagi Bluetooth qurilmalarni tekshirmoqchi boʻlsa, xabar berilsin (tavsiya etiladi)</translation> +<translation id="2315043854645842844">Tanlangan mijoz sertifikati eskirgan va operatsion tizim tomonidan qo‘llab-quvvatlanmaydi.</translation> <translation id="2359808026110333948">Davom etish</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">Yuklab olindi: <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Nusxa olindi</translation> <translation id="2822354292072154809"><ph name="CHOSEN_OBJECT_NAME" /> uchun barcha sayt ruxsatnomalari ilk holatga qaytarilsinmi?</translation> <translation id="2870560284913253234">Sayt</translation> +<translation id="2874939134665556319">Avvalgi musiqa</translation> <translation id="2910701580606108292">Himoyalangan kontentni ijro etishdan avval ruxsat so‘ralsin</translation> <translation id="2913331724188855103">Saytlarga cookie-fayllarini saqlash va o’qishga ruxsat berish (tavsiya etiladi)</translation> <translation id="2968755619301702150">Sertifikatlarni ko‘rish vositasi</translation> <translation id="300526633675317032">Veb-sayt xotirasidan <ph name="SIZE_IN_KB" /> tozalanadi.</translation> +<translation id="301521992641321250">Avtomatik bloklangan</translation> <translation id="3115898365077584848">Ma’lumotlarni ko‘rsatish</translation> <translation id="3123473560110926937">Ayrim saytlarda bloklangan</translation> <translation id="3190152372525844641"><ph name="BEGIN_LINK" />Android sozlamalaridan<ph name="END_LINK" /> Chrome uchun ruxsatnomalarni yoqing.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Orqa fonda sinxronlash</translation> <translation id="3822502789641063741">Sayt xotirasi tozalansinmi?</translation> <translation id="385051799172605136">Orqaga</translation> +<translation id="3859306556332390985">Oldinga surish</translation> <translation id="3955193568934677022">Saytlarga himoyalangan kontentni ijro qilish uchun ruxsat berish (tavsiya etiladi)</translation> <translation id="3987993985790029246">Nusxalash</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">Nomi</translation> <translation id="4008040567710660924">Muayyan saytlar uchun cookie-fayllarga ruxsat berish</translation> +<translation id="4046123991198612571">Keyingi musiqa</translation> <translation id="4165986682804962316">Sayt sozlamalari</translation> <translation id="4226663524361240545">Bildirishnoma kelganida qurilma tebranishi mumkin</translation> <translation id="4242533952199664413">Sozlamalarni ochish</translation> <translation id="4259722352634471385">Sahifa bloklandi: <ph name="URL" /></translation> <translation id="4278390842282768270">Berilgan ruxsatnomalar</translation> +<translation id="429312253194641664">Saytda media-fayl ijro etilmoqda</translation> <translation id="4433925000917964731">Sahifaning Lite versiyasi Google tomonidan taqdim etildi</translation> <translation id="4434045419905280838">Qalquvchi oyna va yo‘naltirishlar</translation> <translation id="445467742685312942">Saytlarga himoyalangan kontentni ijro qilish uchun ruxsat berish</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Qurilma uchun barcha ruxsatnomalarni bekor qilish</translation> <translation id="4964199952259983386">Chrome AR ishlatishi uchun <ph name="BEGIN_LINK" />Android Sozlamalar<ph name="END_LINK" /> orqali kamerani yoqing.</translation> <translation id="497421865427891073">Oldinga</translation> +<translation id="4996978546172906250">Yuborish usuli</translation> <translation id="5039804452771397117">Ruxsat berish</translation> <translation id="5048398596102334565">Saytlarga harakat sensorlaridan foydalanish uchun ruxsat berish (tavsiya etiladi)</translation> <translation id="5063480226653192405">Sarfi</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Tozalash</translation> <translation id="6697925417670533197">Faol yuklanmalar</translation> <translation id="6746124502594467657">Pastga tushish</translation> +<translation id="6766622839693428701">Yopish uchun pastga suring.</translation> <translation id="6782111308708962316">Tashqi saytlarga cookie ma’lumotlarini saqlash va o‘qishni taqiqlash.</translation> +<translation id="6790428901817661496">Ijro etish</translation> <translation id="6818926723028410516">Fayllarni tanlang</translation> <translation id="6864395892908308021">Bu qurilma NFC teglarni oʻqiy olmaydi</translation> <translation id="6910211073230771657">O‘chirib tashlandi</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Sayt kameradan foydalanmoqda</translation> <translation id="7817023149356982970">Bu saytdagi hisobingizdan chiqib ketasiz.</translation> <translation id="7828557259026017104">Cookie fayllar saytlarga tashrif buyurilganda yaratiladigan fayllardir. Saytlar ulardan axborotingizni eslab qolishda foydalanadi. Tashqi cookie fayllar boshqa saytlar tomonidan yaratiladi. Bunday saytlarga ochilgan sahifadagi kontent, reklama yoki rasmlar tegishli boʻlishi mumkin.</translation> +<translation id="7835852323729233924">Mediani ijro etish</translation> <translation id="7846076177841592234">Belgilashni bekor qilish</translation> <translation id="7846621471902887024">Barcha saytdagi hisobingizdan chiqib ketasiz.</translation> <translation id="7882806643839505685">Muayyan saytga ovoz ijro etish uchun ruxsat berish.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Siz haqiqatdan ham bu saytning cookie fayllari kabi barcha ma’lumotlarni o‘chirmoqchimisiz (barcha ruxsatnomalar ilk holatga qaytariladi)?</translation> <translation id="8007176423574883786">Ushbu qurilma uchun o‘chirilgan</translation> <translation id="802154636333426148">Yuklab olib bo‘lmadi</translation> +<translation id="8068648041423924542">Sertifikatni tanlab bo‘lmadi.</translation> <translation id="8087000398470557479"><ph name="DOMAIN_NAME" /> sayti kontenti, Google tomonidan taqdim etildi.</translation> <translation id="8116925261070264013">Ovozsiz</translation> <translation id="8131740175452115882">Tasdiqlash</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Sayt kamera va mikrofondan foydalanmoqda</translation> <translation id="8380167699614421159">Bu saytda yoqimsiz yoki befoyda reklamalar chiqadi</translation> <translation id="8394832520002899662">Saytga qaytish uchun bosing</translation> +<translation id="8425213833346101688">O‘zgartirish</translation> +<translation id="8441146129660941386">Orqaga qaytarish</translation> <translation id="8447861592752582886">Qurilma ruxsatini bekor qilish</translation> <translation id="8463851957836045671">Bu sayt tez</translation> <translation id="851751545965956758">Saytlarga qurilmalarga ulanishni taqiqlash</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Muayyan saytlar uchun cookie-fayllarni bloklang.</translation> <translation id="8959122750345127698">Sahifa topilmadi: <ph name="URL" /></translation> <translation id="9019902583201351841">Ota-onangiz tomonidan boshqariladi</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Mikrofonga ruxsat</translation> <translation id="965817943346481315">Saytlarda chiquvchi yoqimsiz yoki befoyda reklamalar bloklansin (tavsiya etiladi)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_vi.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_vi.xtb index ddd01c91d7c..959084613b6 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_vi.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_vi.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Tiếp theo</translation> <translation id="1242008676835033345">Được nhúng trên <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Dừng</translation> +<translation id="1289742167380433257">Google đã tối ưu hóa các hình ảnh trong trang này để tiết kiệm dữ liệu cho bạn.</translation> <translation id="129382876167171263">Những tệp mà trang web lưu lại sẽ xuất hiện ở đây</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> – <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Đã thêm trang web <ph name="SITE_NAME" /></translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Hỏi trước khi cho phép các trang web tạo bản đồ 3D về các khu vực xung quanh bạn hoặc theo dõi thông tin vị trí của máy ảnh (khuyên dùng)</translation> <translation id="2212565012507486665">Cho phép cookie</translation> <translation id="2289270750774289114">Hỏi khi một trang web muốn tìm các thiết bị Bluetooth ở gần (khuyên dùng)</translation> +<translation id="2315043854645842844">Lựa chọn chứng chỉ phía ứng dụng khách không được hệ điều hành hỗ trợ.</translation> <translation id="2359808026110333948">Tiếp tục</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">Quá trình tải xuống hoàn tất <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Đã sao chép</translation> <translation id="2822354292072154809">Bạn có chắc muốn đặt lại tất cả các quyền của trang web cho <ph name="CHOSEN_OBJECT_NAME" /> không?</translation> <translation id="2870560284913253234">Trang web</translation> +<translation id="2874939134665556319">Bản nhạc trước</translation> <translation id="2910701580606108292">Hỏi trước khi cho phép trang web phát nội dung được bảo vệ</translation> <translation id="2913331724188855103">Cho phép trang web lưu và đọc dữ liệu cookie (được đề xuất)</translation> <translation id="2968755619301702150">Trình xem chứng chỉ</translation> <translation id="300526633675317032">Thao tác này sẽ xóa tất cả <ph name="SIZE_IN_KB" /> bộ nhớ trang web.</translation> +<translation id="301521992641321250">Tự động bị chặn</translation> <translation id="3115898365077584848">Hiển thị thông tin</translation> <translation id="3123473560110926937">Đã chặn trên một số trang web</translation> <translation id="3190152372525844641">Bật quyền cho Chrome trong <ph name="BEGIN_LINK" />Cài đặt Android<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Đồng bộ hóa dưới nền</translation> <translation id="3822502789641063741">Xóa dữ liệu trang trong bộ nhớ?</translation> <translation id="385051799172605136">Quay lại</translation> +<translation id="3859306556332390985">Tìm kiếm tiến</translation> <translation id="3955193568934677022">Cho phép trang web phát nội dung được bảo vệ (được đề xuất)</translation> <translation id="3987993985790029246">Sao chép đường liên kết</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> <translation id="4002066346123236978">Tiêu đề</translation> <translation id="4008040567710660924">Cho phép cookie của một trang web cụ thể.</translation> +<translation id="4046123991198612571">Bản nhạc tiếp theo</translation> <translation id="4165986682804962316">Cài đặt trang web</translation> <translation id="4226663524361240545">Thông báo có thể làm rung thiết bị</translation> <translation id="4242533952199664413">Mở phần cài đặt</translation> <translation id="4259722352634471385">Điều hướng bị chặn: <ph name="URL" /></translation> <translation id="4278390842282768270">Được cho phép</translation> +<translation id="429312253194641664">Một trang web đang phát nội dung đa phương tiện</translation> <translation id="4433925000917964731">Trang phiên bản rút gọn do Google cung cấp</translation> <translation id="4434045419905280838">Cửa sổ bật lên và liên kết chuyển hướng</translation> <translation id="445467742685312942">Cho phép trang web phát nội dung được bảo vệ</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Thu hồi tất cả các quyền đối với thiết bị</translation> <translation id="4964199952259983386">Để cho phép Chrome sử dụng công nghệ thực tế tăng cường (AR), hãy bật cả máy ảnh trong phần <ph name="BEGIN_LINK" />Cài đặt của Android<ph name="END_LINK" />.</translation> <translation id="497421865427891073">Đi về phía trước</translation> +<translation id="4996978546172906250">Chia sẻ qua</translation> <translation id="5039804452771397117">Cho phép</translation> <translation id="5048398596102334565">Cho phép trang web sử dụng cảm biến chuyển động (nên dùng)</translation> <translation id="5063480226653192405">Mức sử dụng</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Xóa</translation> <translation id="6697925417670533197">Hiện đang tải xuống</translation> <translation id="6746124502594467657">Di chuyển xuống</translation> +<translation id="6766622839693428701">Vuốt xuống để đóng.</translation> <translation id="6782111308708962316">Ngăn các trang web của bên thứ ba lưu và đọc dữ liệu cookie</translation> +<translation id="6790428901817661496">Phát</translation> <translation id="6818926723028410516">Chọn mục</translation> <translation id="6864395892908308021">Thiết bị này không hỗ trợ công nghệ Giao tiếp phạm vi gần (NFC)</translation> <translation id="6910211073230771657">Đã xóa</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Một trang web đang sử dụng máy ảnh của bạn</translation> <translation id="7817023149356982970">Bạn sẽ bị đăng xuất khỏi trang web này.</translation> <translation id="7828557259026017104">Cookie là các tệp do các trang web bạn truy cập tạo ra. Các trang web dùng cookie để ghi nhớ lựa chọn của bạn. Cookie bên thứ ba do các trang web khác tạo ra. Các trang web này sở hữu một số nội dung như quảng cáo hoặc hình ảnh mà bạn thấy trên trang web mình truy cập.</translation> +<translation id="7835852323729233924">Đang phát nội dung nghe nhìn</translation> <translation id="7846076177841592234">Hủy chọn</translation> <translation id="7846621471902887024">Bạn sẽ bị đăng xuất khỏi tất cả các trang web.</translation> <translation id="7882806643839505685">Cho phép phát âm thanh trên một trang web cụ thể.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Bạn có chắc chắn muốn xóa tất cả dữ liệu cục bộ, bao gồm cookie và đặt lại tất cả các quyền cho trang web này không?</translation> <translation id="8007176423574883786">Tắt cho thiết bị này</translation> <translation id="802154636333426148">Tải xuống không thành công</translation> +<translation id="8068648041423924542">Không thể chọn chứng chỉ.</translation> <translation id="8087000398470557479">Nội dung này đến từ <ph name="DOMAIN_NAME" />, do Google phân phối.</translation> <translation id="8116925261070264013">Đã ẩn</translation> <translation id="8131740175452115882">Xác nhận</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Một trang web đang sử dụng máy ảnh và micrô của bạn</translation> <translation id="8380167699614421159">Trang web này hiển thị quảng cáo xâm nhập hoặc quảng cáo gây hiểu nhầm</translation> <translation id="8394832520002899662">Nhấn để quay lại trang web</translation> +<translation id="8425213833346101688">Thay đổi</translation> +<translation id="8441146129660941386">Tìm kiếm lùi</translation> <translation id="8447861592752582886">Thu hồi quyền truy cập thiết bị</translation> <translation id="8463851957836045671">Trang web tải nhanh</translation> <translation id="851751545965956758">Chặn các trang web kết nối với thiết bị</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Chặn cookie của một trang web cụ thể.</translation> <translation id="8959122750345127698">Không thể tiếp cận điều hướng: <ph name="URL" /></translation> <translation id="9019902583201351841">Do cha mẹ của bạn quản lý</translation> +<translation id="9074739597929991885">Bluetooth</translation> <translation id="945632385593298557">Truy cập micrô của bạn</translation> <translation id="965817943346481315">Chặn nếu trang web hiển thị quảng cáo xâm nhập hoặc quảng cáo gây hiểu nhầm (khuyên dùng)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_zh-CN.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_zh-CN.xtb index e3010ddcff0..5bba417ee1b 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_zh-CN.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_zh-CN.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">下一步</translation> <translation id="1242008676835033345">嵌入来源:<ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">停止</translation> +<translation id="1289742167380433257">为节省您的流量,Google 已优化了此网页中的图片。</translation> <translation id="129382876167171263">网站保存的文件会显示在这里</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> - <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">网站 <ph name="SITE_NAME" /> 已添加</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">在允许网站为您的周边环境创建 3D 地图或跟踪摄像头位置之前询问您(推荐)</translation> <translation id="2212565012507486665">允许使用 Cookie</translation> <translation id="2289270750774289114">在网站想发现附近的蓝牙设备时询问您(推荐)</translation> +<translation id="2315043854645842844">操作系统不支持选择客户端证书。</translation> <translation id="2359808026110333948">继续</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">下载完成 <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">已复制</translation> <translation id="2822354292072154809">确定要重置<ph name="CHOSEN_OBJECT_NAME" />的所有网站权限吗?</translation> <translation id="2870560284913253234">网站</translation> +<translation id="2874939134665556319">上一首</translation> <translation id="2910701580606108292">网站需先询问并得到许可才能播放受保护内容</translation> <translation id="2913331724188855103">允许网站保存和读取 Cookie 数据(推荐)</translation> <translation id="2968755619301702150">证书查看器</translation> <translation id="300526633675317032">这会清除全部的网站存储数据 (<ph name="SIZE_IN_KB" />)。</translation> +<translation id="301521992641321250">已被自动禁止</translation> <translation id="3115898365077584848">显示信息</translation> <translation id="3123473560110926937">已禁止部分网站显示广告</translation> <translation id="3190152372525844641">在 <ph name="BEGIN_LINK" />Android 设置<ph name="END_LINK" />中为 Chrome 启用这些权限。</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">后台同步</translation> <translation id="3822502789641063741">要清除网站存储数据吗?</translation> <translation id="385051799172605136">返回</translation> +<translation id="3859306556332390985">前进</translation> <translation id="3955193568934677022">允许网站播放受保护的内容(推荐)</translation> <translation id="3987993985790029246">复制链接</translation> <translation id="3991845972263764475">已下载 <ph name="BYTES_DOWNLOADED_WITH_UNITS" />,总大小不明</translation> <translation id="4002066346123236978">标题</translation> <translation id="4008040567710660924">允许特定网站使用 Cookie。</translation> +<translation id="4046123991198612571">下一曲</translation> <translation id="4165986682804962316">网站设置</translation> <translation id="4226663524361240545">收到通知时设备会振动</translation> <translation id="4242533952199664413">打开“设置”</translation> <translation id="4259722352634471385">已屏蔽 <ph name="URL" /></translation> <translation id="4278390842282768270">允许</translation> +<translation id="429312253194641664">某个网站正在播放媒体内容</translation> <translation id="4433925000917964731">由 Google 提供的精简版网页</translation> <translation id="4434045419905280838">弹出式窗口和重定向</translation> <translation id="445467742685312942">允许网站播放受保护内容。</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">撤消设备的所有权限</translation> <translation id="4964199952259983386">若要允许 Chrome 使用 AR 功能,您还需在 <ph name="BEGIN_LINK" />Android 设置<ph name="END_LINK" />中开启摄像头。</translation> <translation id="497421865427891073">前进</translation> +<translation id="4996978546172906250">分享方式</translation> <translation id="5039804452771397117">允许</translation> <translation id="5048398596102334565">允许网站使用动态传感器(推荐)</translation> <translation id="5063480226653192405">使用情况</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">清除</translation> <translation id="6697925417670533197">正在下载内容</translation> <translation id="6746124502594467657">下移</translation> +<translation id="6766622839693428701">向下滑动即可关闭。</translation> <translation id="6782111308708962316">阻止第三方网站保存和读取 Cookie 数据</translation> +<translation id="6790428901817661496">播放</translation> <translation id="6818926723028410516">选择内容</translation> <translation id="6864395892908308021">此设备无法读取 NFC 数据</translation> <translation id="6910211073230771657">已删除</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">有一个网站正在使用您的摄像头</translation> <translation id="7817023149356982970">您将会退出此网站。</translation> <translation id="7828557259026017104">Cookie 是由您访问过的网站创建的文件,供网站用来记住您的偏好;第三方 Cookie 是由其他网站创建而成,这些网站是您在所访问网页上看到的部分内容(比如广告或图片)的所有方。</translation> +<translation id="7835852323729233924">正在播放媒体</translation> <translation id="7846076177841592234">取消选择</translation> <translation id="7846621471902887024">您将会自动退出所有网站。</translation> <translation id="7882806643839505685">允许特定网站播放声音。</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">确定要清除该网站的所有本地数据(包括 Cookie)并重置该网站的所有权限吗?</translation> <translation id="8007176423574883786">已对此设备停用</translation> <translation id="802154636333426148">下载失败</translation> +<translation id="8068648041423924542">无法选择证书。</translation> <translation id="8087000398470557479">此内容来自 <ph name="DOMAIN_NAME" />(由 Google 提供)。</translation> <translation id="8116925261070264013">已静音的网站</translation> <translation id="8131740175452115882">确认</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">有一个网站正在使用您的摄像头和麦克风</translation> <translation id="8380167699614421159">此网站会展示侵扰性或误导性广告</translation> <translation id="8394832520002899662">点按即可返回到网站</translation> +<translation id="8425213833346101688">更改</translation> +<translation id="8441146129660941386">后退</translation> <translation id="8447861592752582886">撤消设备权限</translation> <translation id="8463851957836045671">网站加载速度很快</translation> <translation id="851751545965956758">禁止网站连接到设备</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">阻止特定网站使用 Cookie。</translation> <translation id="8959122750345127698">无法访问 <ph name="URL" /></translation> <translation id="9019902583201351841">由您父母管理</translation> +<translation id="9074739597929991885">蓝牙</translation> <translation id="945632385593298557">使用您的麦克风</translation> <translation id="965817943346481315">屏蔽会展示侵扰性或误导性广告的网站(推荐)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_zh-HK.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_zh-HK.xtb index 45c6f7b1c81..03756536183 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_zh-HK.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_zh-HK.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">下一個</translation> <translation id="1242008676835033345">嵌入至 <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">停止</translation> +<translation id="1289742167380433257">Google 已優化此網頁的圖片,以節省數據用量。</translation> <translation id="129382876167171263">網站儲存的檔案會在這裡顯示</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> - <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">已新增網站 <ph name="SITE_NAME" /></translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">在允許網站建立您身處環境的 3D 地圖或追蹤攝錄機位置前先詢問您 (建議)</translation> <translation id="2212565012507486665">允許 Cookie</translation> <translation id="2289270750774289114">在網站要探索附近的藍牙裝置時詢問您 (建議)</translation> +<translation id="2315043854645842844">作業系統不支援由客戶端選取憑證。</translation> <translation id="2359808026110333948">繼續</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">下載完成 <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">已複製</translation> <translation id="2822354292072154809">確定要重設「<ph name="CHOSEN_OBJECT_NAME" />」的所有網站權限嗎?</translation> <translation id="2870560284913253234">網站</translation> +<translation id="2874939134665556319">上一首曲目</translation> <translation id="2910701580606108292">網站播放受保護內容前先詢問您</translation> <translation id="2913331724188855103">允許網站儲存及讀取 Cookie 資料 (建議)</translation> <translation id="2968755619301702150">憑證檢視者</translation> <translation id="300526633675317032">這會將網站儲存空間的 <ph name="SIZE_IN_KB" /> 資料全部清除。</translation> +<translation id="301521992641321250">已自動封鎖</translation> <translation id="3115898365077584848">顯示資料</translation> <translation id="3123473560110926937">在部分網站上設定封鎖</translation> <translation id="3190152372525844641">已在「<ph name="BEGIN_LINK" />Android 設定<ph name="END_LINK" />」中為 Chrome 開啟權限。</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">背景同步處理</translation> <translation id="3822502789641063741">要清除網站儲存空間的資料嗎?</translation> <translation id="385051799172605136">返回</translation> +<translation id="3859306556332390985">向前快轉</translation> <translation id="3955193568934677022">允許網站播放受保護的內容 (建議)</translation> <translation id="3987993985790029246">複製連結</translation> <translation id="3991845972263764475">已下載:<ph name="BYTES_DOWNLOADED_WITH_UNITS" />,總大小:不明</translation> <translation id="4002066346123236978">標題</translation> <translation id="4008040567710660924">允許特定網站存取 Cookie。</translation> +<translation id="4046123991198612571">下一首曲目</translation> <translation id="4165986682804962316">網站設定</translation> <translation id="4226663524361240545">裝置會在收到通知時震動</translation> <translation id="4242533952199664413">開啟設定</translation> <translation id="4259722352634471385">瀏覽網址被封鎖:<ph name="URL" /></translation> <translation id="4278390842282768270">已允許</translation> +<translation id="429312253194641664">網站正在播放媒體</translation> <translation id="4433925000917964731">此簡易版網頁由 Google 提供</translation> <translation id="4434045419905280838">彈出式視窗和重新導向</translation> <translation id="445467742685312942">允許網站播放受保護的內容</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">撤銷裝置所有的權限</translation> <translation id="4964199952259983386">如要讓 Chrome 使用 AR,請在「<ph name="BEGIN_LINK" />Android 設定<ph name="END_LINK" />」中開啟相機。</translation> <translation id="497421865427891073">往前</translation> +<translation id="4996978546172906250">共用方式</translation> <translation id="5039804452771397117">允許</translation> <translation id="5048398596102334565">允許網站存取動作感應器 (建議)</translation> <translation id="5063480226653192405">用量</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">清除</translation> <translation id="6697925417670533197">正在下載的項目</translation> <translation id="6746124502594467657">下移</translation> +<translation id="6766622839693428701">向下掃就可以閂咗佢。</translation> <translation id="6782111308708962316">禁止第三方網站儲存及讀取 Cookie 資料</translation> +<translation id="6790428901817661496">播放</translation> <translation id="6818926723028410516">選取項目</translation> <translation id="6864395892908308021">此裝置無法讀取 NFC</translation> <translation id="6910211073230771657">已刪除</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">有網站正在使用您的相機</translation> <translation id="7817023149356982970">您將會從這個網站登出。</translation> <translation id="7828557259026017104">Cookie 是您瀏覽的網站所建立的檔案,網站會使用這些檔案記住您的偏好設定,第三方 Cookie 則由其他網站建立。這些網站擁有您所瀏覽網頁的部分內容,例如廣告和圖片。</translation> +<translation id="7835852323729233924">正在播放媒體</translation> <translation id="7846076177841592234">取消選取</translation> <translation id="7846621471902887024">您將會從所有網站登出。</translation> <translation id="7882806643839505685">允許特定網站播放音效。</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">您確定要清除這個網站的所有本機資料 (包括 Cookie),然後重設其所有權限嗎?</translation> <translation id="8007176423574883786">已為這部裝置關閉</translation> <translation id="802154636333426148">下載失敗</translation> +<translation id="8068648041423924542">無法選擇憑證。</translation> <translation id="8087000398470557479">此內容來自 <ph name="DOMAIN_NAME" />,由 Google 提供。</translation> <translation id="8116925261070264013">已設為靜音的網站</translation> <translation id="8131740175452115882">確定</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">有網站正在使用您的相機和麥克風</translation> <translation id="8380167699614421159">此網站顯示滋擾性或誤導廣告</translation> <translation id="8394832520002899662">輕按即可返回網站</translation> +<translation id="8425213833346101688">變更</translation> +<translation id="8441146129660941386">向後回轉</translation> <translation id="8447861592752582886">撤消裝置權限</translation> <translation id="8463851957836045671">網站快速</translation> <translation id="851751545965956758">禁止網站連接裝置</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">禁止特定網站存取 Cookie。</translation> <translation id="8959122750345127698">無法存取瀏覽網址:<ph name="URL" /></translation> <translation id="9019902583201351841">由您的家長管理</translation> +<translation id="9074739597929991885">藍牙</translation> <translation id="945632385593298557">存取您的麥克風</translation> <translation id="965817943346481315">封鎖顯示滋擾性或誤導廣告網站上的廣告 (建議)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_zh-TW.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_zh-TW.xtb index 53d66504c81..ca1de8d8405 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_zh-TW.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_zh-TW.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">繼續</translation> <translation id="1242008676835033345">嵌入至 <ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">停止</translation> +<translation id="1289742167380433257">Google 已將這個頁面的圖片進行最佳化處理,為你節省資料用量。</translation> <translation id="129382876167171263">網站儲存的檔案會顯示在這裡</translation> <translation id="1364532808393826295"><ph name="APP_NAME" /> - <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">已新增 <ph name="SITE_NAME" /> 網站</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">網站必須先詢問你,才能根據你的周遭環境建立 3D 地圖或追蹤攝影機位置 (建議)</translation> <translation id="2212565012507486665">允許 Cookie</translation> <translation id="2289270750774289114">當網站要搜尋附近的藍牙裝置時,必須先詢問你 (建議)</translation> +<translation id="2315043854645842844">作業系統不允許您在用戶端選取憑證。</translation> <translation id="2359808026110333948">繼續</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">下載完成 <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">已複製</translation> <translation id="2822354292072154809">確定要重設「<ph name="CHOSEN_OBJECT_NAME" />」的所有網站權限嗎?</translation> <translation id="2870560284913253234">網站</translation> +<translation id="2874939134665556319">上一首曲目</translation> <translation id="2910701580606108292">允許網站播放受保護的內容前,必須先詢問你</translation> <translation id="2913331724188855103">允許網站儲存及讀取 Cookie 資料 (建議)</translation> <translation id="2968755619301702150">憑證檢視器</translation> <translation id="300526633675317032">這會將網站儲存的資料全部清除 (共 <ph name="SIZE_IN_KB" />)。</translation> +<translation id="301521992641321250">已自動封鎖</translation> <translation id="3115898365077584848">顯示資訊</translation> <translation id="3123473560110926937">在某些網站上設定封鎖</translation> <translation id="3190152372525844641">請在 <ph name="BEGIN_LINK" />Android 設定<ph name="END_LINK" />中為 Chrome 啟用這些權限。</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">背景同步處理</translation> <translation id="3822502789641063741">要清除網站儲存的資料嗎?</translation> <translation id="385051799172605136">返回</translation> +<translation id="3859306556332390985">快轉到特定的播放時間點</translation> <translation id="3955193568934677022">允許網站播放受保護的內容 (建議)</translation> <translation id="3987993985790029246">複製連結</translation> <translation id="3991845972263764475">已下載:<ph name="BYTES_DOWNLOADED_WITH_UNITS" />,總大小:不明</translation> <translation id="4002066346123236978">標題</translation> <translation id="4008040567710660924">允許特定網站的 Cookie。</translation> +<translation id="4046123991198612571">下一首曲目</translation> <translation id="4165986682804962316">網站設定</translation> <translation id="4226663524361240545">收到通知時裝置會震動</translation> <translation id="4242533952199664413">開啟設定</translation> <translation id="4259722352634471385">瀏覽的網址已封鎖:<ph name="URL" /></translation> <translation id="4278390842282768270">允許</translation> +<translation id="429312253194641664">一個網站正在播放媒體內容</translation> <translation id="4433925000917964731">由 Google 提供的精簡版網頁</translation> <translation id="4434045419905280838">彈出式視窗與重新導向</translation> <translation id="445467742685312942">允許網站播放受保護的內容</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">撤銷裝置的所有權限</translation> <translation id="4964199952259983386">如要允許 Chrome 使用 AR,請一併開啟 <ph name="BEGIN_LINK" />Android 設定<ph name="END_LINK" />中的攝影機。</translation> <translation id="497421865427891073">往前</translation> +<translation id="4996978546172906250">分享方式:</translation> <translation id="5039804452771397117">允許</translation> <translation id="5048398596102334565">允許網站存取動作感應器 (建議)</translation> <translation id="5063480226653192405">用量</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">清除</translation> <translation id="6697925417670533197">正在下載的項目</translation> <translation id="6746124502594467657">下移</translation> +<translation id="6766622839693428701">向下滑動即可關閉。</translation> <translation id="6782111308708962316">禁止第三方網站儲存及讀取 Cookie 資料</translation> +<translation id="6790428901817661496">播放</translation> <translation id="6818926723028410516">選取項目</translation> <translation id="6864395892908308021">這部裝置無法讀取 NFC</translation> <translation id="6910211073230771657">已刪除</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">有網站正在使用你的攝影機</translation> <translation id="7817023149356982970">系統會將你登出這個網站。</translation> <translation id="7828557259026017104">Cookie 是你造訪過的網站所建立的檔案,網站會使用這些檔案記住你的偏好設定。第三方 Cookie 由其他網站所建立。這類網站通常是在你造訪的網站上提供部分內容 (例如廣告或圖片) 的其他網站。</translation> +<translation id="7835852323729233924">正在播放媒體</translation> <translation id="7846076177841592234">全部取消選取</translation> <translation id="7846621471902887024">系統會將你登出所有網站。</translation> <translation id="7882806643839505685">允許特定網站播放音訊。</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">確定要刪除這個網站儲存的所有本機資料 (包括 Cookie 在內),並重設這個網站的所有權限嗎?</translation> <translation id="8007176423574883786">已在這個裝置上關閉</translation> <translation id="802154636333426148">下載失敗</translation> +<translation id="8068648041423924542">無法選取憑證。</translation> <translation id="8087000398470557479">這個內容來自 <ph name="DOMAIN_NAME" />,由 Google 所提供。</translation> <translation id="8116925261070264013">已設為靜音</translation> <translation id="8131740175452115882">確認</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">有網站正在使用你的攝影機和麥克風</translation> <translation id="8380167699614421159">這個網站會顯示干擾性或誤導性的廣告</translation> <translation id="8394832520002899662">輕觸即可返回網站</translation> +<translation id="8425213833346101688">變更</translation> +<translation id="8441146129660941386">倒轉到特定的播放時間點</translation> <translation id="8447861592752582886">撤銷裝置權限</translation> <translation id="8463851957836045671">這個網站的載入速度很快</translation> <translation id="851751545965956758">禁止網站連線至裝置</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">封鎖特定網站的 Cookie。</translation> <translation id="8959122750345127698">瀏覽的網址無法存取:<ph name="URL" /></translation> <translation id="9019902583201351841">你的家長已停用這項功能</translation> +<translation id="9074739597929991885">藍牙</translation> <translation id="945632385593298557">存取您的麥克風</translation> <translation id="965817943346481315">封鎖干擾性或誤導性的網站廣告 (建議)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_zu.xtb b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_zu.xtb index a7627d00562..9f089ae8998 100644 --- a/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_zu.xtb +++ b/chromium/components/browser_ui/strings/android/translations/browser_ui_strings_zu.xtb @@ -10,6 +10,7 @@ <translation id="1201402288615127009">Okulandelayo</translation> <translation id="1242008676835033345">Ishumekwe ku-<ph name="WEBSITE_URL" /></translation> <translation id="1272079795634619415">Misa</translation> +<translation id="1289742167380433257">Ukuze ulondoloze idatha, izithombe zaleli khasi zizolungiselelwa yi-Google.</translation> <translation id="129382876167171263">Amafayela ngamawebhusayithi abonakala lapha</translation> <translation id="1364532808393826295"><ph name="APP_NAME" />, <ph name="NOTIFICATION_MESSAGE" /></translation> <translation id="1369915414381695676">Isayithi le-<ph name="SITE_NAME" /> lingeziwe</translation> @@ -42,6 +43,7 @@ <translation id="2182457891543959921">Buza ngaphambi kokuvumela amasayithi ukudala imephu ye-3D yendawo ekuzungezile noma ukulandelela indawo yekhamera (kuyanconywa)</translation> <translation id="2212565012507486665">Vumela amakhukhi</translation> <translation id="2289270750774289114">Buza uma isayithi lifuna ukuthola amadivayisi aseduze e-Bluetooth (kunconyiwe)</translation> +<translation id="2315043854645842844">Ukukhethwa kwesitifiketi sohlangothi lweklayenti akusekelwe yisistimu yokusebenza.</translation> <translation id="2359808026110333948">Qhubeka</translation> <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2434158240863470628">Ukulanda kuqedile <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> @@ -61,10 +63,12 @@ <translation id="2704606927547763573">Kukopishiwe</translation> <translation id="2822354292072154809">Ingabe uqinisekile ukuthi ufuna ukusetha kabusha zonke izimvume zesayithi le-<ph name="CHOSEN_OBJECT_NAME" />?</translation> <translation id="2870560284913253234">Isayithi</translation> +<translation id="2874939134665556319">Ithrekhi yangaphambilini</translation> <translation id="2910701580606108292">Buza ngaphambi kokuvumela amasayithi ukudlala okuqukethwe okuvikelwe</translation> <translation id="2913331724188855103">Vumela amasayithi ukulondoloza nokufunda idatha yamakhukhi (kunconyiwe)</translation> <translation id="2968755619301702150">Isibukeli sesitifiketi</translation> <translation id="300526633675317032">Lokhu kuzosula yonke i-<ph name="SIZE_IN_KB" /> yesitoreji sewebhusayithi.</translation> +<translation id="301521992641321250">Kuvinjelwe ngokuzenzakalelayo</translation> <translation id="3115898365077584848">Khombisa ulwazi</translation> <translation id="3123473560110926937">Kuvinjelwe kwamanye amasayithi</translation> <translation id="3190152372525844641">Vula izimvume ze-Chrome <ph name="BEGIN_LINK" />kuzilungiselelo ze-Android<ph name="END_LINK" />.</translation> @@ -83,16 +87,19 @@ <translation id="3744111561329211289">Ukuvumelanisa ngemuva</translation> <translation id="3822502789641063741">Sula isitoreji sesayithi?</translation> <translation id="385051799172605136">Emuva</translation> +<translation id="3859306556332390985">Funela phambili</translation> <translation id="3955193568934677022">Vumela amasayithi ukudlala okuqukethwe okuvikelwe (kunconyiwe)</translation> <translation id="3987993985790029246">Kopisha isixhumanisi</translation> <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="4002066346123236978">Isihloko</translation> <translation id="4008040567710660924">Vumela amakhukhi esayithi elithile.</translation> +<translation id="4046123991198612571">Ithrekhi elandelayo</translation> <translation id="4165986682804962316">Izilungiselelo zesayithi</translation> <translation id="4226663524361240545">Izaziso zingadlidliza idivayisi</translation> <translation id="4242533952199664413">Vula izilungiselelo</translation> <translation id="4259722352634471385">Ukuzulazula kuvinjiwe: <ph name="URL" /></translation> <translation id="4278390842282768270">Kuvunyelwe</translation> +<translation id="429312253194641664">Isayithi lidlala imidiya</translation> <translation id="4433925000917964731">Ikhasi elilula linikezwe i-Google</translation> <translation id="4434045419905280838">Okwesikhashana nokuqondiswa kabusha</translation> <translation id="445467742685312942">Vumela amasayithi ukudlala okuqukethwe okuvikelekile</translation> @@ -107,6 +114,7 @@ <translation id="4962975101802056554">Buyisa zonke izimvume zedivayisi</translation> <translation id="4964199952259983386">Vumela i-Chrome ukusebenzisa i-AR, futhi vula ikhamera kokuthi <ph name="BEGIN_LINK" />Izilungiselelo ze-Android<ph name="END_LINK" />.</translation> <translation id="497421865427891073">Iya phambili</translation> +<translation id="4996978546172906250">Yabelana nge-</translation> <translation id="5039804452771397117">Vumela</translation> <translation id="5048398596102334565">Vumela amasayithi ukuthi afinyelele kuzinzwa zokunyakaza (kunconyiwe)</translation> <translation id="5063480226653192405">Ukusetshenziswa</translation> @@ -163,7 +171,9 @@ <translation id="6643016212128521049">Sula</translation> <translation id="6697925417670533197">Ukulanda okusebenzayo</translation> <translation id="6746124502594467657">Hambisa phansi</translation> +<translation id="6766622839693428701">Swayiphela phansi ukuze uvale.</translation> <translation id="6782111308708962316">Vimbela amawebhusayithi enkampani yangaphandle kusukela ekulondolozeni nasekufundeni idatha yamakhukhi</translation> +<translation id="6790428901817661496">Dlala</translation> <translation id="6818926723028410516">Khetha izinto</translation> <translation id="6864395892908308021">Le divayisi ayikwazi ukufunda i-NFC</translation> <translation id="6910211073230771657">Kususiwe</translation> @@ -197,6 +207,7 @@ <translation id="7804248752222191302">Isayithi lisebenzisa ikhamera yakho</translation> <translation id="7817023149356982970">Uzokhishwa ngemvume kule sayithi.</translation> <translation id="7828557259026017104">Amakhukhi amafayela adalwe amawebhusayithi owavakashelayo. Amasayithi ayawasebenzisa ukukhumbula okuncamelayo. Amakhukhi wenkampani yangaphandle adalwa ngamanye amasayithi. Lamasayithi aphethe okunye okuqukethwe, njengezikhangiso noma izithombe, ozibona ekhasini lewebhu olivakashelayo.</translation> +<translation id="7835852323729233924">Ukudlala imidiya</translation> <translation id="7846076177841592234">Khansela ukukhetha</translation> <translation id="7846621471902887024">Uzokhishwa ngemvume kuwo wonke amasayithi</translation> <translation id="7882806643839505685">Vumela umsindo wesayithi elithile.</translation> @@ -204,6 +215,7 @@ <translation id="7999064672810608036">Ingabe uqinisekile ukuthi ufuna ukususa yonke idatha yasendaweni, efaka amakhukhi, uphinde usethe kabusha zonke izimvume zale webhusayithi?</translation> <translation id="8007176423574883786">Kuvaliwe kule divayisi</translation> <translation id="802154636333426148">Ukulanda kwehlulekile</translation> +<translation id="8068648041423924542">Ayikwazi ukukhetha isitifiketi.</translation> <translation id="8087000398470557479">Lokhu okuqukethwe kubuya ku-<ph name="DOMAIN_NAME" />, kulethwa i-Google.</translation> <translation id="8116925261070264013">Kuthulisiwe</translation> <translation id="8131740175452115882">Qinisekisa</translation> @@ -216,6 +228,8 @@ <translation id="83792324527827022">Isayithi lisebenzisa ikhamera nemakrofoni yakho</translation> <translation id="8380167699614421159">Leli sayithi libonisa izikhangiso ezingathandeki noma ezidukisayo</translation> <translation id="8394832520002899662">Thepha ukubuyela kusayithi</translation> +<translation id="8425213833346101688">Guqula</translation> +<translation id="8441146129660941386">Funela emuva</translation> <translation id="8447861592752582886">Buyisa imvume yedivayisi</translation> <translation id="8463851957836045671">Isayithi liyashesha</translation> <translation id="851751545965956758">Vimbela amasayithi kusukela ekuxhumekeni kumadivayisi</translation> @@ -236,6 +250,7 @@ <translation id="8958424370300090006">Vimbela amakhukhi kusayithi elithile.</translation> <translation id="8959122750345127698">Ukuzulazula akufinyeleleki: <ph name="URL" /></translation> <translation id="9019902583201351841">Kuphethwa abazali bakho</translation> +<translation id="9074739597929991885">I-Bluetooth</translation> <translation id="945632385593298557">Finyelela imakrofoni yakho</translation> <translation id="965817943346481315">Vimba uma isayithi libonisa izikhangiso ezingathandeki noma ezidukisayo (kunconyiwe)</translation> </translationbundle>
\ No newline at end of file diff --git a/chromium/components/browser_ui/styles/android/BUILD.gn b/chromium/components/browser_ui/styles/android/BUILD.gn index df181094a3d..f8d1a9e3184 100644 --- a/chromium/components/browser_ui/styles/android/BUILD.gn +++ b/chromium/components/browser_ui/styles/android/BUILD.gn @@ -11,6 +11,7 @@ android_library("java") { ":java_resources", "//base:base_java", "//third_party/android_deps:android_support_v7_appcompat_java", + "//third_party/android_deps:androidx_appcompat_appcompat_resources_java", ] } @@ -25,45 +26,78 @@ android_resources("java_resources") { "java/res/color/default_icon_color_tint_list.xml", "java/res/drawable-hdpi/ic_delete_white_24dp.png", "java/res/drawable-hdpi/ic_folder_blue_24dp.png", + "java/res/drawable-hdpi/ic_pause_white_24dp.png", + "java/res/drawable-hdpi/ic_pause_white_36dp.png", + "java/res/drawable-hdpi/ic_play_arrow_white_24dp.png", + "java/res/drawable-hdpi/ic_play_arrow_white_36dp.png", "java/res/drawable-hdpi/ic_stop_white_36dp.png", "java/res/drawable-hdpi/ic_videocam_white_24dp.png", "java/res/drawable-hdpi/infobar_downloading.png", "java/res/drawable-hdpi/modern_toolbar_shadow.png", "java/res/drawable-hdpi/plus.png", "java/res/drawable-hdpi/settings_all_sites.png", + "java/res/drawable-hdpi/top_round.9.png", "java/res/drawable-mdpi/ic_delete_white_24dp.png", "java/res/drawable-mdpi/ic_folder_blue_24dp.png", + "java/res/drawable-mdpi/ic_pause_white_24dp.png", + "java/res/drawable-mdpi/ic_pause_white_36dp.png", + "java/res/drawable-mdpi/ic_play_arrow_white_24dp.png", + "java/res/drawable-mdpi/ic_play_arrow_white_36dp.png", "java/res/drawable-mdpi/ic_stop_white_36dp.png", "java/res/drawable-mdpi/ic_videocam_white_24dp.png", "java/res/drawable-mdpi/infobar_downloading.png", "java/res/drawable-mdpi/modern_toolbar_shadow.png", "java/res/drawable-mdpi/plus.png", "java/res/drawable-mdpi/settings_all_sites.png", + "java/res/drawable-mdpi/top_round.9.png", + "java/res/drawable-night-hdpi/top_round.9.png", + "java/res/drawable-night-mdpi/top_round.9.png", + "java/res/drawable-night-xhdpi/top_round.9.png", + "java/res/drawable-night-xxhdpi/top_round.9.png", + "java/res/drawable-night-xxxhdpi/top_round.9.png", "java/res/drawable-xhdpi/ic_delete_white_24dp.png", "java/res/drawable-xhdpi/ic_folder_blue_24dp.png", + "java/res/drawable-xhdpi/ic_pause_white_24dp.png", + "java/res/drawable-xhdpi/ic_pause_white_36dp.png", + "java/res/drawable-xhdpi/ic_play_arrow_white_24dp.png", + "java/res/drawable-xhdpi/ic_play_arrow_white_36dp.png", "java/res/drawable-xhdpi/ic_stop_white_36dp.png", "java/res/drawable-xhdpi/ic_videocam_white_24dp.png", "java/res/drawable-xhdpi/infobar_downloading.png", "java/res/drawable-xhdpi/modern_toolbar_shadow.png", "java/res/drawable-xhdpi/plus.png", "java/res/drawable-xhdpi/settings_all_sites.png", + "java/res/drawable-xhdpi/top_round.9.png", "java/res/drawable-xxhdpi/ic_delete_white_24dp.png", "java/res/drawable-xxhdpi/ic_folder_blue_24dp.png", + "java/res/drawable-xxhdpi/ic_pause_white_24dp.png", + "java/res/drawable-xxhdpi/ic_pause_white_36dp.png", + "java/res/drawable-xxhdpi/ic_play_arrow_white_24dp.png", + "java/res/drawable-xxhdpi/ic_play_arrow_white_36dp.png", "java/res/drawable-xxhdpi/ic_stop_white_36dp.png", "java/res/drawable-xxhdpi/ic_videocam_white_24dp.png", "java/res/drawable-xxhdpi/infobar_downloading.png", "java/res/drawable-xxhdpi/modern_toolbar_shadow.png", "java/res/drawable-xxhdpi/plus.png", "java/res/drawable-xxhdpi/settings_all_sites.png", + "java/res/drawable-xxhdpi/top_round.9.png", "java/res/drawable-xxxhdpi/ic_delete_white_24dp.png", "java/res/drawable-xxxhdpi/ic_folder_blue_24dp.png", + "java/res/drawable-xxxhdpi/ic_pause_white_24dp.png", + "java/res/drawable-xxxhdpi/ic_pause_white_36dp.png", + "java/res/drawable-xxxhdpi/ic_play_arrow_white_24dp.png", + "java/res/drawable-xxxhdpi/ic_play_arrow_white_36dp.png", "java/res/drawable-xxxhdpi/ic_stop_white_36dp.png", "java/res/drawable-xxxhdpi/ic_videocam_white_24dp.png", "java/res/drawable-xxxhdpi/infobar_downloading.png", "java/res/drawable-xxxhdpi/plus.png", "java/res/drawable-xxxhdpi/settings_all_sites.png", + "java/res/drawable-xxxhdpi/top_round.9.png", "java/res/drawable/ic_help_and_feedback.xml", "java/res/drawable/ic_offline_pin_24dp_on_light_bg.xml", + "java/res/drawable/ic_security_grey.xml", + "java/res/drawable/ic_update_grey.xml", + "java/res/drawable/ic_vpn_key_grey.xml", "java/res/drawable/permission_location.xml", "java/res/values-night/colors.xml", "java/res/values/colors.xml", diff --git a/chromium/components/browser_ui/styles/android/java/res/color/default_icon_color_light_tint_list.xml b/chromium/components/browser_ui/styles/android/java/res/color/default_icon_color_light_tint_list.xml index 31e780762db..545e91cb0da 100644 --- a/chromium/components/browser_ui/styles/android/java/res/color/default_icon_color_light_tint_list.xml +++ b/chromium/components/browser_ui/styles/android/java/res/color/default_icon_color_light_tint_list.xml @@ -8,15 +8,11 @@ <selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:ignore="UnusedResources"> - <item android:alpha="@dimen/default_icon_pressed_alpha" - android:state_selected="true" android:color="@color/default_icon_color_light" /> - <item android:alpha="@dimen/default_icon_pressed_alpha" - android:state_focused="true" android:color="@color/default_icon_color_light" /> - <item android:alpha="@dimen/default_icon_pressed_alpha" - android:state_pressed="true" android:color="@color/default_icon_color_light" /> - <item android:alpha="@dimen/default_icon_pressed_alpha" - android:state_activated="true" android:color="@color/default_icon_color_light" /> <item android:alpha="@dimen/default_disabled_alpha" android:state_enabled="false" android:color="@color/default_icon_color_light" /> + <item android:state_selected="true" android:color="@color/default_icon_color_light" /> + <item android:state_focused="true" android:color="@color/default_icon_color_light" /> + <item android:state_pressed="true" android:color="@color/default_icon_color_light" /> + <item android:state_activated="true" android:color="@color/default_icon_color_light" /> <item android:color="@color/default_icon_color_light" /> </selector> diff --git a/chromium/components/browser_ui/styles/android/java/res/drawable-hdpi/ic_pause_white_24dp.png b/chromium/components/browser_ui/styles/android/java/res/drawable-hdpi/ic_pause_white_24dp.png Binary files differnew file mode 100644 index 00000000000..1701f34b01c --- /dev/null +++ b/chromium/components/browser_ui/styles/android/java/res/drawable-hdpi/ic_pause_white_24dp.png diff --git a/chromium/components/browser_ui/styles/android/java/res/drawable-hdpi/ic_pause_white_36dp.png b/chromium/components/browser_ui/styles/android/java/res/drawable-hdpi/ic_pause_white_36dp.png Binary files differnew file mode 100644 index 00000000000..caa2c77768c --- /dev/null +++ b/chromium/components/browser_ui/styles/android/java/res/drawable-hdpi/ic_pause_white_36dp.png diff --git a/chromium/components/browser_ui/styles/android/java/res/drawable-hdpi/ic_play_arrow_white_24dp.png b/chromium/components/browser_ui/styles/android/java/res/drawable-hdpi/ic_play_arrow_white_24dp.png Binary files differnew file mode 100644 index 00000000000..35f2e7f6df5 --- /dev/null +++ b/chromium/components/browser_ui/styles/android/java/res/drawable-hdpi/ic_play_arrow_white_24dp.png diff --git a/chromium/components/browser_ui/styles/android/java/res/drawable-hdpi/ic_play_arrow_white_36dp.png b/chromium/components/browser_ui/styles/android/java/res/drawable-hdpi/ic_play_arrow_white_36dp.png Binary files differnew file mode 100644 index 00000000000..29adeed052e --- /dev/null +++ b/chromium/components/browser_ui/styles/android/java/res/drawable-hdpi/ic_play_arrow_white_36dp.png diff --git a/chromium/components/browser_ui/styles/android/java/res/drawable-hdpi/top_round.9.png b/chromium/components/browser_ui/styles/android/java/res/drawable-hdpi/top_round.9.png Binary files differnew file mode 100644 index 00000000000..0b1d52afa0b --- /dev/null +++ b/chromium/components/browser_ui/styles/android/java/res/drawable-hdpi/top_round.9.png diff --git a/chromium/components/browser_ui/styles/android/java/res/drawable-mdpi/ic_pause_white_24dp.png b/chromium/components/browser_ui/styles/android/java/res/drawable-mdpi/ic_pause_white_24dp.png Binary files differnew file mode 100644 index 00000000000..e1169e56ff6 --- /dev/null +++ b/chromium/components/browser_ui/styles/android/java/res/drawable-mdpi/ic_pause_white_24dp.png diff --git a/chromium/components/browser_ui/styles/android/java/res/drawable-mdpi/ic_pause_white_36dp.png b/chromium/components/browser_ui/styles/android/java/res/drawable-mdpi/ic_pause_white_36dp.png Binary files differnew file mode 100644 index 00000000000..1701f34b01c --- /dev/null +++ b/chromium/components/browser_ui/styles/android/java/res/drawable-mdpi/ic_pause_white_36dp.png diff --git a/chromium/components/browser_ui/styles/android/java/res/drawable-mdpi/ic_play_arrow_white_24dp.png b/chromium/components/browser_ui/styles/android/java/res/drawable-mdpi/ic_play_arrow_white_24dp.png Binary files differnew file mode 100644 index 00000000000..cc060f1a080 --- /dev/null +++ b/chromium/components/browser_ui/styles/android/java/res/drawable-mdpi/ic_play_arrow_white_24dp.png diff --git a/chromium/components/browser_ui/styles/android/java/res/drawable-mdpi/ic_play_arrow_white_36dp.png b/chromium/components/browser_ui/styles/android/java/res/drawable-mdpi/ic_play_arrow_white_36dp.png Binary files differnew file mode 100644 index 00000000000..35f2e7f6df5 --- /dev/null +++ b/chromium/components/browser_ui/styles/android/java/res/drawable-mdpi/ic_play_arrow_white_36dp.png diff --git a/chromium/components/browser_ui/styles/android/java/res/drawable-mdpi/top_round.9.png b/chromium/components/browser_ui/styles/android/java/res/drawable-mdpi/top_round.9.png Binary files differnew file mode 100644 index 00000000000..20dfd1d6fbf --- /dev/null +++ b/chromium/components/browser_ui/styles/android/java/res/drawable-mdpi/top_round.9.png diff --git a/chromium/components/browser_ui/styles/android/java/res/drawable-night-hdpi/top_round.9.png b/chromium/components/browser_ui/styles/android/java/res/drawable-night-hdpi/top_round.9.png Binary files differnew file mode 100644 index 00000000000..25891a03726 --- /dev/null +++ b/chromium/components/browser_ui/styles/android/java/res/drawable-night-hdpi/top_round.9.png diff --git a/chromium/components/browser_ui/styles/android/java/res/drawable-night-mdpi/top_round.9.png b/chromium/components/browser_ui/styles/android/java/res/drawable-night-mdpi/top_round.9.png Binary files differnew file mode 100644 index 00000000000..dfee2710b30 --- /dev/null +++ b/chromium/components/browser_ui/styles/android/java/res/drawable-night-mdpi/top_round.9.png diff --git a/chromium/components/browser_ui/styles/android/java/res/drawable-night-xhdpi/top_round.9.png b/chromium/components/browser_ui/styles/android/java/res/drawable-night-xhdpi/top_round.9.png Binary files differnew file mode 100644 index 00000000000..aaad5198012 --- /dev/null +++ b/chromium/components/browser_ui/styles/android/java/res/drawable-night-xhdpi/top_round.9.png diff --git a/chromium/components/browser_ui/styles/android/java/res/drawable-night-xxhdpi/top_round.9.png b/chromium/components/browser_ui/styles/android/java/res/drawable-night-xxhdpi/top_round.9.png Binary files differnew file mode 100644 index 00000000000..e167a10f58d --- /dev/null +++ b/chromium/components/browser_ui/styles/android/java/res/drawable-night-xxhdpi/top_round.9.png diff --git a/chromium/components/browser_ui/styles/android/java/res/drawable-night-xxxhdpi/top_round.9.png b/chromium/components/browser_ui/styles/android/java/res/drawable-night-xxxhdpi/top_round.9.png Binary files differnew file mode 100644 index 00000000000..f1d02de72ee --- /dev/null +++ b/chromium/components/browser_ui/styles/android/java/res/drawable-night-xxxhdpi/top_round.9.png diff --git a/chromium/components/browser_ui/styles/android/java/res/drawable-xhdpi/ic_pause_white_24dp.png b/chromium/components/browser_ui/styles/android/java/res/drawable-xhdpi/ic_pause_white_24dp.png Binary files differnew file mode 100644 index 00000000000..f49aed75711 --- /dev/null +++ b/chromium/components/browser_ui/styles/android/java/res/drawable-xhdpi/ic_pause_white_24dp.png diff --git a/chromium/components/browser_ui/styles/android/java/res/drawable-xhdpi/ic_pause_white_36dp.png b/chromium/components/browser_ui/styles/android/java/res/drawable-xhdpi/ic_pause_white_36dp.png Binary files differnew file mode 100644 index 00000000000..7192ad487ea --- /dev/null +++ b/chromium/components/browser_ui/styles/android/java/res/drawable-xhdpi/ic_pause_white_36dp.png diff --git a/chromium/components/browser_ui/styles/android/java/res/drawable-xhdpi/ic_play_arrow_white_24dp.png b/chromium/components/browser_ui/styles/android/java/res/drawable-xhdpi/ic_play_arrow_white_24dp.png Binary files differnew file mode 100644 index 00000000000..a3c80e73daa --- /dev/null +++ b/chromium/components/browser_ui/styles/android/java/res/drawable-xhdpi/ic_play_arrow_white_24dp.png diff --git a/chromium/components/browser_ui/styles/android/java/res/drawable-xhdpi/ic_play_arrow_white_36dp.png b/chromium/components/browser_ui/styles/android/java/res/drawable-xhdpi/ic_play_arrow_white_36dp.png Binary files differnew file mode 100644 index 00000000000..547ef30aacd --- /dev/null +++ b/chromium/components/browser_ui/styles/android/java/res/drawable-xhdpi/ic_play_arrow_white_36dp.png diff --git a/chromium/components/browser_ui/styles/android/java/res/drawable-xhdpi/top_round.9.png b/chromium/components/browser_ui/styles/android/java/res/drawable-xhdpi/top_round.9.png Binary files differnew file mode 100644 index 00000000000..35ce64c4dda --- /dev/null +++ b/chromium/components/browser_ui/styles/android/java/res/drawable-xhdpi/top_round.9.png diff --git a/chromium/components/browser_ui/styles/android/java/res/drawable-xxhdpi/ic_pause_white_24dp.png b/chromium/components/browser_ui/styles/android/java/res/drawable-xxhdpi/ic_pause_white_24dp.png Binary files differnew file mode 100644 index 00000000000..7192ad487ea --- /dev/null +++ b/chromium/components/browser_ui/styles/android/java/res/drawable-xxhdpi/ic_pause_white_24dp.png diff --git a/chromium/components/browser_ui/styles/android/java/res/drawable-xxhdpi/ic_pause_white_36dp.png b/chromium/components/browser_ui/styles/android/java/res/drawable-xxhdpi/ic_pause_white_36dp.png Binary files differnew file mode 100644 index 00000000000..a03bad27edd --- /dev/null +++ b/chromium/components/browser_ui/styles/android/java/res/drawable-xxhdpi/ic_pause_white_36dp.png diff --git a/chromium/components/browser_ui/styles/android/java/res/drawable-xxhdpi/ic_play_arrow_white_24dp.png b/chromium/components/browser_ui/styles/android/java/res/drawable-xxhdpi/ic_play_arrow_white_24dp.png Binary files differnew file mode 100644 index 00000000000..547ef30aacd --- /dev/null +++ b/chromium/components/browser_ui/styles/android/java/res/drawable-xxhdpi/ic_play_arrow_white_24dp.png diff --git a/chromium/components/browser_ui/styles/android/java/res/drawable-xxhdpi/ic_play_arrow_white_36dp.png b/chromium/components/browser_ui/styles/android/java/res/drawable-xxhdpi/ic_play_arrow_white_36dp.png Binary files differnew file mode 100644 index 00000000000..23bb1ba9f68 --- /dev/null +++ b/chromium/components/browser_ui/styles/android/java/res/drawable-xxhdpi/ic_play_arrow_white_36dp.png diff --git a/chromium/components/browser_ui/styles/android/java/res/drawable-xxhdpi/top_round.9.png b/chromium/components/browser_ui/styles/android/java/res/drawable-xxhdpi/top_round.9.png Binary files differnew file mode 100644 index 00000000000..e88e33970cd --- /dev/null +++ b/chromium/components/browser_ui/styles/android/java/res/drawable-xxhdpi/top_round.9.png diff --git a/chromium/components/browser_ui/styles/android/java/res/drawable-xxxhdpi/ic_pause_white_24dp.png b/chromium/components/browser_ui/styles/android/java/res/drawable-xxxhdpi/ic_pause_white_24dp.png Binary files differnew file mode 100644 index 00000000000..660ac658589 --- /dev/null +++ b/chromium/components/browser_ui/styles/android/java/res/drawable-xxxhdpi/ic_pause_white_24dp.png diff --git a/chromium/components/browser_ui/styles/android/java/res/drawable-xxxhdpi/ic_pause_white_36dp.png b/chromium/components/browser_ui/styles/android/java/res/drawable-xxxhdpi/ic_pause_white_36dp.png Binary files differnew file mode 100644 index 00000000000..3ea7e03e5dc --- /dev/null +++ b/chromium/components/browser_ui/styles/android/java/res/drawable-xxxhdpi/ic_pause_white_36dp.png diff --git a/chromium/components/browser_ui/styles/android/java/res/drawable-xxxhdpi/ic_play_arrow_white_24dp.png b/chromium/components/browser_ui/styles/android/java/res/drawable-xxxhdpi/ic_play_arrow_white_24dp.png Binary files differnew file mode 100644 index 00000000000..be5c062b5fe --- /dev/null +++ b/chromium/components/browser_ui/styles/android/java/res/drawable-xxxhdpi/ic_play_arrow_white_24dp.png diff --git a/chromium/components/browser_ui/styles/android/java/res/drawable-xxxhdpi/ic_play_arrow_white_36dp.png b/chromium/components/browser_ui/styles/android/java/res/drawable-xxxhdpi/ic_play_arrow_white_36dp.png Binary files differnew file mode 100644 index 00000000000..2745c3ab929 --- /dev/null +++ b/chromium/components/browser_ui/styles/android/java/res/drawable-xxxhdpi/ic_play_arrow_white_36dp.png diff --git a/chromium/components/browser_ui/styles/android/java/res/drawable-xxxhdpi/top_round.9.png b/chromium/components/browser_ui/styles/android/java/res/drawable-xxxhdpi/top_round.9.png Binary files differnew file mode 100644 index 00000000000..3df273c1425 --- /dev/null +++ b/chromium/components/browser_ui/styles/android/java/res/drawable-xxxhdpi/top_round.9.png diff --git a/chromium/components/browser_ui/styles/android/java/res/drawable/ic_security_grey.xml b/chromium/components/browser_ui/styles/android/java/res/drawable/ic_security_grey.xml new file mode 100644 index 00000000000..3d022d7b088 --- /dev/null +++ b/chromium/components/browser_ui/styles/android/java/res/drawable/ic_security_grey.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Copyright 2020 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.--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="@android:color/white" + android:pathData="M12,1L3,5v6c0,5.55 3.84,10.74 9,12 5.16,-1.26 9,-6.45 9,-12L21,5l-9,-4zM12,11.99h7c-0.53,4.12 -3.28,7.79 -7,8.94L12,12L5,12L5,6.3l7,-3.11v8.8z"/> +</vector> diff --git a/chromium/components/browser_ui/styles/android/java/res/drawable/ic_update_grey.xml b/chromium/components/browser_ui/styles/android/java/res/drawable/ic_update_grey.xml new file mode 100644 index 00000000000..84c22bde410 --- /dev/null +++ b/chromium/components/browser_ui/styles/android/java/res/drawable/ic_update_grey.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Copyright 2020 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.--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="@android:color/white" + android:pathData="M21,10.12h-6.78l2.74,-2.82c-2.73,-2.7 -7.15,-2.8 -9.88,-0.1 -2.73,2.71 -2.73,7.08 0,9.79 2.73,2.71 7.15,2.71 9.88,0C18.32,15.65 19,14.08 19,12.1h2c0,1.98 -0.88,4.55 -2.64,6.29 -3.51,3.48 -9.21,3.48 -12.72,0 -3.5,-3.47 -3.53,-9.11 -0.02,-12.58 3.51,-3.47 9.14,-3.47 12.65,0L21,3v7.12zM12.5,8v4.25l3.5,2.08 -0.72,1.21L11,13V8h1.5z"/> +</vector> diff --git a/chromium/components/browser_ui/styles/android/java/res/drawable/ic_vpn_key_grey.xml b/chromium/components/browser_ui/styles/android/java/res/drawable/ic_vpn_key_grey.xml new file mode 100644 index 00000000000..58bf849f60a --- /dev/null +++ b/chromium/components/browser_ui/styles/android/java/res/drawable/ic_vpn_key_grey.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Copyright 2019 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.--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:targetApi="21" android:width="24dp" android:height="24dp" android:viewportWidth="24.0" android:viewportHeight="24.0"> + <path android:pathData="M7.5 6c2.796 0 5.145 1.912 5.811 4.5H22.5v3h-2V18H17v-4.5h-3.69C12.646 16.089 10.297 18 7.5 18c-3.314 0-6-2.686-6-6s2.686-6 6-6zm0 3.5C6.12 9.5 5 10.62 5 12s1.12 2.5 2.5 2.5S10 13.38 10 12 8.88 9.5 7.5 9.5z" android:strokeWidth="1" android:fillColor="@android:color/white" android:fillType="evenOdd"/> +</vector> diff --git a/chromium/components/browser_ui/util/android/BUILD.gn b/chromium/components/browser_ui/util/android/BUILD.gn index 5b7a7d3e0a4..3e582066cba 100644 --- a/chromium/components/browser_ui/util/android/BUILD.gn +++ b/chromium/components/browser_ui/util/android/BUILD.gn @@ -10,6 +10,9 @@ android_library("java") { "java/src/org/chromium/components/browser_ui/util/ComposedBrowserControlsVisibilityDelegate.java", "java/src/org/chromium/components/browser_ui/util/ConversionUtils.java", "java/src/org/chromium/components/browser_ui/util/DownloadUtils.java", + "java/src/org/chromium/components/browser_ui/util/date/CalendarFactory.java", + "java/src/org/chromium/components/browser_ui/util/date/CalendarUtils.java", + "java/src/org/chromium/components/browser_ui/util/date/StringUtils.java", ] deps = [ @@ -17,6 +20,7 @@ android_library("java") { "//base:base_java", "//components/embedder_support/android:util_java", "//content/public/android:content_java", + "//third_party/android_deps:androidx_core_core_java", ] } @@ -44,5 +48,9 @@ java_library("junit") { "//base:base_java_test_support", "//base:base_junit_test_support", "//base/test:test_support_java", + "//content/public/android:content_java", + "//third_party/android_deps:robolectric_all_java", + "//third_party/junit", + "//third_party/mockito:mockito_java", ] } diff --git a/chromium/components/browser_ui/util/android/java/src/org/chromium/components/browser_ui/util/date/CalendarFactory.java b/chromium/components/browser_ui/util/android/java/src/org/chromium/components/browser_ui/util/date/CalendarFactory.java new file mode 100644 index 00000000000..af194842f39 --- /dev/null +++ b/chromium/components/browser_ui/util/android/java/src/org/chromium/components/browser_ui/util/date/CalendarFactory.java @@ -0,0 +1,44 @@ +// Copyright 2018 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.components.browser_ui.util.date; + +import org.chromium.base.task.AsyncTask; +import org.chromium.base.task.BackgroundOnlyAsyncTask; + +import java.util.Calendar; +import java.util.concurrent.ExecutionException; + +/** Helper class to simplify querying for a {@link Calendar} instance. */ +public final class CalendarFactory { + private static final AsyncTask<Calendar> sCalendarBuilder = + new CalendarBuilder().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + + private CalendarFactory() {} + + /** + * + * @return A unique {@link Calendar} instance. This version will (1) not be handed out to any + * other caller and (2) will be completely reset. + */ + public static Calendar get() { + Calendar calendar = null; + try { + calendar = (Calendar) sCalendarBuilder.get().clone(); + } catch (InterruptedException | ExecutionException e) { + // We've tried our best. If AsyncTask really does not work, we give up. :( + calendar = Calendar.getInstance(); + } + + calendar.clear(); + return calendar; + } + + private static class CalendarBuilder extends BackgroundOnlyAsyncTask<Calendar> { + @Override + protected Calendar doInBackground() { + return Calendar.getInstance(); + } + } +} diff --git a/chromium/components/browser_ui/util/android/java/src/org/chromium/components/browser_ui/util/date/CalendarUtils.java b/chromium/components/browser_ui/util/android/java/src/org/chromium/components/browser_ui/util/date/CalendarUtils.java new file mode 100644 index 00000000000..8f22e69d090 --- /dev/null +++ b/chromium/components/browser_ui/util/android/java/src/org/chromium/components/browser_ui/util/date/CalendarUtils.java @@ -0,0 +1,57 @@ +// Copyright 2018 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.components.browser_ui.util.date; + +import java.util.Calendar; + +/** A set of utility methods meant to make interacting with a {@link Calendar} instance easier. */ +public final class CalendarUtils { + private static final class LazyHolder { + private static Calendar sCalendar1 = CalendarFactory.get(); + private static Calendar sCalendar2 = CalendarFactory.get(); + } + + private CalendarUtils() {} + + /** + * Helper method to return the start of the day according to the localized {@link Calendar}. + * This instance will have no hour, minute, second, etc. associated with it. Only year, month, + * and day of month. + * @param t The timestamp (in milliseconds) since epoch. + * @return A {@link Calendar} instance representing the beginning of the day denoted by + * {@code t}. + */ + public static Calendar getStartOfDay(long t) { + LazyHolder.sCalendar1.setTimeInMillis(t); + + int year = LazyHolder.sCalendar1.get(Calendar.YEAR); + int month = LazyHolder.sCalendar1.get(Calendar.MONTH); + int day = LazyHolder.sCalendar1.get(Calendar.DATE); + LazyHolder.sCalendar1.clear(); + LazyHolder.sCalendar1.set(year, month, day, 0, 0, 0); + + return LazyHolder.sCalendar1; + } + + /** + * Helper method determining whether or not two timestamps occur on the same localized calendar + * day. + * @param t1 A timestamp (in milliseconds) since epoch. + * @param t2 A timestamp (in milliseconds) since epoch. + * @return Whether or not {@code t1} and {@code t2} represent times on the same localized + * calendar day. + */ + public static boolean isSameDay(long t1, long t2) { + LazyHolder.sCalendar1.setTimeInMillis(t1); + LazyHolder.sCalendar2.setTimeInMillis(t2); + return isSameDay(LazyHolder.sCalendar1, LazyHolder.sCalendar2); + } + + /** @return Whether {@code cal1} and {@code cal2} have the same localized calendar day. */ + public static boolean isSameDay(Calendar cal1, Calendar cal2) { + return cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR) + && cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR); + } +}
\ No newline at end of file diff --git a/chromium/components/browser_ui/util/android/java/src/org/chromium/components/browser_ui/util/date/StringUtils.java b/chromium/components/browser_ui/util/android/java/src/org/chromium/components/browser_ui/util/date/StringUtils.java new file mode 100644 index 00000000000..510d03d0fdc --- /dev/null +++ b/chromium/components/browser_ui/util/android/java/src/org/chromium/components/browser_ui/util/date/StringUtils.java @@ -0,0 +1,52 @@ +// Copyright 2020 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.components.browser_ui.util.date; + +import android.content.Context; +import android.text.format.DateUtils; + +import org.chromium.base.ContextUtils; +import org.chromium.components.browser_ui.util.R; + +import java.util.Calendar; +import java.util.Date; + +/** Helper methods to deal with converting dates to various strings. */ +public class StringUtils { + private static final class LazyHolder { + private static Calendar sCalendar1 = CalendarFactory.get(); + private static Calendar sCalendar2 = CalendarFactory.get(); + } + + private StringUtils() {} + + /** + * Converts {@code date} into a string meant to be used as a list header. + * @param date The {@link Date} to convert. + * @return The {@link CharSequence} representing the header. + */ + public static CharSequence dateToHeaderString(Date date) { + Context context = ContextUtils.getApplicationContext(); + + LazyHolder.sCalendar1.setTimeInMillis(System.currentTimeMillis()); + LazyHolder.sCalendar2.setTime(date); + + StringBuilder builder = new StringBuilder(); + if (CalendarUtils.isSameDay(LazyHolder.sCalendar1, LazyHolder.sCalendar2)) { + builder.append(context.getString(R.string.today)).append(" - "); + } else { + LazyHolder.sCalendar1.add(Calendar.DATE, -1); + if (CalendarUtils.isSameDay(LazyHolder.sCalendar1, LazyHolder.sCalendar2)) { + builder.append(context.getString(R.string.yesterday)).append(" - "); + } + } + + builder.append(DateUtils.formatDateTime(context, date.getTime(), + DateUtils.FORMAT_ABBREV_WEEKDAY | DateUtils.FORMAT_ABBREV_MONTH + | DateUtils.FORMAT_SHOW_YEAR)); + + return builder; + } +}
\ No newline at end of file diff --git a/chromium/components/browser_ui/webshare/OWNERS b/chromium/components/browser_ui/webshare/OWNERS new file mode 100644 index 00000000000..c880f89d823 --- /dev/null +++ b/chromium/components/browser_ui/webshare/OWNERS @@ -0,0 +1,5 @@ +ericwilligers@chromium.org +raymes@chromium.org + +# COMPONENT: Blink>WebShare +# OS: Android diff --git a/chromium/components/browser_ui/webshare/android/BUILD.gn b/chromium/components/browser_ui/webshare/android/BUILD.gn new file mode 100644 index 00000000000..05149697937 --- /dev/null +++ b/chromium/components/browser_ui/webshare/android/BUILD.gn @@ -0,0 +1,42 @@ +# Copyright 2020 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. + +import("//build/config/android/rules.gni") + +android_library("java") { + sources = [ + "java/src/org/chromium/components/browser_ui/webshare/BlobReceiver.java", + "java/src/org/chromium/components/browser_ui/webshare/ShareServiceImpl.java", + "java/src/org/chromium/components/browser_ui/webshare/SharedFileCollator.java", + ] + deps = [ + "//base:base_java", + "//components/browser_ui/share/android:java", + "//content/public/android:content_java", + "//mojo/public/java:system_java", + "//mojo/public/java/system:system_impl_java", + "//third_party/blink/public/mojom:android_mojo_bindings_java", + "//ui/android:ui_java", + "//url/mojom:url_mojom_gurl_java", + ] +} + +java_library("junit") { + # Skip platform checks since Robolectric depends on requires_android targets. + bypass_platform_checks = true + testonly = true + sources = [ + "java/src/org/chromium/components/browser_ui/webshare/ShareServiceImplTest.java", + "java/src/org/chromium/components/browser_ui/webshare/SharedFileCollatorTest.java", + ] + deps = [ + ":java", + "//base:base_java", + "//base:base_java_test_support", + "//base:base_junit_test_support", + "//base/test:test_support_java", + "//third_party/blink/public/mojom:android_mojo_bindings_java", + "//third_party/junit", + ] +} diff --git a/chromium/components/browser_ui/webshare/android/DEPS b/chromium/components/browser_ui/webshare/android/DEPS new file mode 100644 index 00000000000..bb311370365 --- /dev/null +++ b/chromium/components/browser_ui/webshare/android/DEPS @@ -0,0 +1,5 @@ +include_rules = [ + "+mojo/public/java/system", + "+content/public/android/java", + "+ui/android/java", +] diff --git a/chromium/components/browser_ui/webshare/android/java/src/org/chromium/components/browser_ui/webshare/BlobReceiver.java b/chromium/components/browser_ui/webshare/android/java/src/org/chromium/components/browser_ui/webshare/BlobReceiver.java new file mode 100644 index 00000000000..e1008c3c68f --- /dev/null +++ b/chromium/components/browser_ui/webshare/android/java/src/org/chromium/components/browser_ui/webshare/BlobReceiver.java @@ -0,0 +1,177 @@ +// Copyright 2019 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.components.browser_ui.webshare; + +import org.chromium.base.Callback; +import org.chromium.base.Log; +import org.chromium.base.StreamUtil; +import org.chromium.blink.mojom.Blob; +import org.chromium.blink.mojom.BlobReaderClient; +import org.chromium.mojo.system.Core; +import org.chromium.mojo.system.DataPipe; +import org.chromium.mojo.system.MojoException; +import org.chromium.mojo.system.MojoResult; +import org.chromium.mojo.system.Pair; +import org.chromium.mojo.system.ResultAnd; +import org.chromium.mojo.system.Watcher; +import org.chromium.mojo.system.impl.CoreImpl; + +import java.io.IOException; +import java.io.OutputStream; +import java.nio.ByteBuffer; + +/** + * Receives a blob over mojom and writes it to the stream. + */ +public class BlobReceiver implements BlobReaderClient { + private static final String TAG = "share"; + private static final int CHUNK_SIZE = 64 * 1024; + private static final int PIPE_CAPACITY = 2 * CHUNK_SIZE; + + private final ByteBuffer mBuffer; + private final OutputStream mOutputStream; + private long mMaximumContentSize; + private long mExpectedContentSize; + private long mReceivedContentSize; + private DataPipe.ConsumerHandle mConsumerHandle; + private Callback<Integer> mCallback; + + /** + * Constructs a BlobReceiver. + * + * @param outputStream the destination for the blob contents. + * @param maximumContentSize the maximum permitted length of the blob. + */ + public BlobReceiver(OutputStream outputStream, long maximumContentSize) { + mBuffer = ByteBuffer.allocateDirect(CHUNK_SIZE); + mOutputStream = outputStream; + mMaximumContentSize = maximumContentSize; + } + + /** + * Initiates reading of the blob contents. + * + * @param blob the blob to read. + * @param callback the callback to call when reading is complete. + */ + public void start(Blob blob, Callback<Integer> callback) { + mCallback = callback; + DataPipe.CreateOptions options = new DataPipe.CreateOptions(); + options.setElementNumBytes(1); + options.setCapacityNumBytes(PIPE_CAPACITY); + + Pair<DataPipe.ProducerHandle, DataPipe.ConsumerHandle> pipe = + CoreImpl.getInstance().createDataPipe(options); + mConsumerHandle = pipe.second; + blob.readAll(pipe.first, this); + } + + // Interface + @Override + public void close() {} + + // ConnectionErrorHandler + @Override + public void onConnectionError(MojoException e) { + if (mCallback == null) return; + reportError(e.getMojoResult(), "Connection error detected."); + } + + // BlobReaderClient + @Override + public void onCalculatedSize(long totalSize, long expectedContentSize) { + if (mCallback == null) return; + if (expectedContentSize > mMaximumContentSize) { + reportError(MojoResult.RESOURCE_EXHAUSTED, "Stream exceeds permitted size"); + return; + } + mExpectedContentSize = expectedContentSize; + if (mReceivedContentSize >= mExpectedContentSize) { + complete(); + return; + } + + Watcher watcher = CoreImpl.getInstance().getWatcher(); + watcher.start(mConsumerHandle, Core.HandleSignals.READABLE, new Watcher.Callback() { + @Override + public void onResult(int result) { + if (mCallback == null) return; + if (result == MojoResult.OK) { + read(); + } else { + reportError(result, "Watcher reported error."); + } + } + }); + } + + // BlobReaderClient + @Override + public void onComplete(int status, long dataLength) { + if (mCallback == null) return; + read(); + } + + private void read() { + try { + while (true) { + ResultAnd<Integer> result = + mConsumerHandle.readData(mBuffer, DataPipe.ReadFlags.NONE); + + if (result.getMojoResult() == MojoResult.SHOULD_WAIT) return; + + if (result.getMojoResult() != MojoResult.OK) { + reportError(result.getMojoResult(), "Failed to read from blob."); + return; + } + + Integer bytesRead = result.getValue(); + if (bytesRead <= 0) { + reportError(MojoResult.SHOULD_WAIT, "No data available"); + return; + } + try { + mOutputStream.write(mBuffer.array(), mBuffer.arrayOffset(), bytesRead); + } catch (IOException e) { + reportError(MojoResult.DATA_LOSS, "Failed to write to stream."); + return; + } + mReceivedContentSize += bytesRead; + if (mReceivedContentSize >= mExpectedContentSize) { + if (mReceivedContentSize == mExpectedContentSize) { + complete(); + } else { + reportError( + MojoResult.OUT_OF_RANGE, "Received more bytes than expected size."); + } + return; + } + } + } catch (MojoException e) { + reportError(e.getMojoResult(), "Failed to receive blob."); + } + } + + private void complete() { + try { + mOutputStream.close(); + } catch (IOException e) { + reportError(MojoResult.CANCELLED, "Failed to close stream."); + return; + } + mCallback.onResult(MojoResult.OK); + mCallback = null; + } + + private void reportError(int result, String message) { + if (result == MojoResult.OK) { + result = MojoResult.INVALID_ARGUMENT; + } + Log.w(TAG, message); + StreamUtil.closeQuietly(mOutputStream); + mCallback.onResult(result); + mCallback = null; + } +} diff --git a/chromium/components/browser_ui/webshare/android/java/src/org/chromium/components/browser_ui/webshare/ShareServiceImpl.java b/chromium/components/browser_ui/webshare/android/java/src/org/chromium/components/browser_ui/webshare/ShareServiceImpl.java new file mode 100644 index 00000000000..dcdc8ddc798 --- /dev/null +++ b/chromium/components/browser_ui/webshare/android/java/src/org/chromium/components/browser_ui/webshare/ShareServiceImpl.java @@ -0,0 +1,290 @@ +// Copyright 2016 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.components.browser_ui.webshare; + +import android.app.Activity; +import android.content.ComponentName; +import android.net.Uri; + +import androidx.annotation.Nullable; + +import org.chromium.base.CollectionUtil; +import org.chromium.base.ContentUriUtils; +import org.chromium.base.FileUtils; +import org.chromium.base.Log; +import org.chromium.base.metrics.RecordHistogram; +import org.chromium.base.task.AsyncTask; +import org.chromium.base.task.PostTask; +import org.chromium.base.task.TaskRunner; +import org.chromium.base.task.TaskTraits; +import org.chromium.components.browser_ui.share.ShareImageFileUtils; +import org.chromium.components.browser_ui.share.ShareParams; +import org.chromium.content_public.browser.WebContents; +import org.chromium.mojo.system.MojoException; +import org.chromium.ui.base.WindowAndroid; +import org.chromium.url.mojom.Url; +import org.chromium.webshare.mojom.ShareError; +import org.chromium.webshare.mojom.ShareService; +import org.chromium.webshare.mojom.SharedFile; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Set; + +/** + * Android implementation of the ShareService service defined in + * third_party/blink/public/mojom/webshare/webshare.mojom. + */ +public class ShareServiceImpl implements ShareService { + private final WindowAndroid mWindow; + private final WebShareDelegate mDelegate; + + private static final String TAG = "share"; + + // These numbers are written to histograms. Keep in sync with WebShareMethod enum in + // histograms.xml, and don't reuse or renumber entries (except for the _COUNT entry). + private static final int WEBSHARE_METHOD_SHARE = 0; + // Count is technically 1, but recordEnumeratedHistogram requires a boundary of at least 2 + // (https://crbug.com/645032). + private static final int WEBSHARE_METHOD_COUNT = 2; + + // These numbers are written to histograms. Keep in sync with WebShareOutcome enum in + // histograms.xml, and don't reuse or renumber entries (except for the _COUNT entry). + private static final int WEBSHARE_OUTCOME_SUCCESS = 0; + private static final int WEBSHARE_OUTCOME_UNKNOWN_FAILURE = 1; + private static final int WEBSHARE_OUTCOME_CANCELED = 2; + private static final int WEBSHARE_OUTCOME_COUNT = 3; + + // These protect us if the renderer is compromised. + private static final int MAX_SHARED_FILE_COUNT = 10; + private static final int MAX_SHARED_FILE_BYTES = 50 * 1024 * 1024; + + // clang-format off + private static final Set<String> PERMITTED_EXTENSIONS = + Collections.unmodifiableSet(CollectionUtil.newHashSet( + "bmp", // image/bmp / image/x-ms-bmp + "css", // text/css + "csv", // text/csv / text/comma-separated-values + "ehtml", // text/html + "flac", // audio/flac + "gif", // image/gif + "htm", // text/html + "html", // text/html + "ico", // image/x-icon + "jfif", // image/jpeg + "jpeg", // image/jpeg + "jpg", // image/jpeg + "m4a", // audio/x-m4a + "m4v", // video/mp4 + "mp3", // audio/mp3 + "mp4", // video/mp4 + "mpeg", // video/mpeg + "mpg", // video/mpeg + "oga", // audio/ogg + "ogg", // audio/ogg + "ogm", // video/ogg + "ogv", // video/ogg + "opus", // audio/ogg + "pjp", // image/jpeg + "pjpeg", // image/jpeg + "png", // image/png + "shtm", // text/html + "shtml", // text/html + "svg", // image/svg+xml + "svgz", // image/svg+xml + "text", // text/plain + "tif", // image/tiff + "tiff", // image/tiff + "txt", // text/plain + "wav", // audio/wav + "weba", // audio/webm + "webm", // video/webm + "webp", // image/webp + "xbm" // image/x-xbitmap + )); + + private static final Set<String> PERMITTED_MIME_TYPES = + Collections.unmodifiableSet(CollectionUtil.newHashSet( + "audio/flac", + "audio/mp3", + "audio/ogg", + "audio/wav", + "audio/webm", + "audio/x-m4a", + "image/bmp", + "image/gif", + "image/jpeg", + "image/png", + "image/svg+xml", + "image/tiff", + "image/webp", + "image/x-icon", + "image/x-ms-bmp", + "image/x-xbitmap", + "text/comma-separated-values", + "text/css", + "text/csv", + "text/html", + "text/plain", + "video/mp4", + "video/mpeg", + "video/ogg", + "video/webm" + )); + // clang-format on + + private static final TaskRunner TASK_RUNNER = + PostTask.createSequencedTaskRunner(TaskTraits.USER_BLOCKING); + + /** Delegate class that provides embedder-specific functionality. */ + public interface WebShareDelegate { + /** + * @return true if sharing is currently possible. + */ + public boolean canShare(); + + /** + * Overridden by the embedder to execute the share. + * @param params the share data. + */ + public void share(ShareParams params); + } + + public ShareServiceImpl(@Nullable WebContents webContents, WebShareDelegate delegate) { + mWindow = webContents.getTopLevelNativeWindow(); + mDelegate = delegate; + } + + @Override + public void close() {} + + @Override + public void onConnectionError(MojoException e) {} + + @Override + public void share(String title, String text, Url url, final SharedFile[] files, + final ShareResponse callback) { + RecordHistogram.recordEnumeratedHistogram( + "WebShare.ApiCount", WEBSHARE_METHOD_SHARE, WEBSHARE_METHOD_COUNT); + + if (!mDelegate.canShare()) { + RecordHistogram.recordEnumeratedHistogram("WebShare.ShareOutcome", + WEBSHARE_OUTCOME_UNKNOWN_FAILURE, WEBSHARE_OUTCOME_COUNT); + callback.call(ShareError.INTERNAL_ERROR); + return; + } + + ShareParams.TargetChosenCallback innerCallback = new ShareParams.TargetChosenCallback() { + @Override + public void onTargetChosen(ComponentName chosenComponent) { + RecordHistogram.recordEnumeratedHistogram( + "WebShare.ShareOutcome", WEBSHARE_OUTCOME_SUCCESS, WEBSHARE_OUTCOME_COUNT); + callback.call(ShareError.OK); + } + + @Override + public void onCancel() { + RecordHistogram.recordEnumeratedHistogram( + "WebShare.ShareOutcome", WEBSHARE_OUTCOME_CANCELED, WEBSHARE_OUTCOME_COUNT); + callback.call(ShareError.CANCELED); + } + }; + + final ShareParams.Builder paramsBuilder = new ShareParams.Builder(mWindow, title, url.url) + .setText(text) + .setCallback(innerCallback); + if (files == null || files.length == 0) { + mDelegate.share(paramsBuilder.build()); + return; + } + + if (files.length > MAX_SHARED_FILE_COUNT) { + callback.call(ShareError.PERMISSION_DENIED); + return; + } + + for (SharedFile file : files) { + if (isDangerousFilename(file.name) || isDangerousMimeType(file.blob.contentType)) { + Log.i(TAG, + "Cannot share potentially dangerous \"" + file.blob.contentType + + "\" file \"" + file.name + "\"."); + callback.call(ShareError.PERMISSION_DENIED); + return; + } + } + + new AsyncTask<Boolean>() { + @Override + protected void onPostExecute(Boolean result) { + if (result.equals(Boolean.FALSE)) { + callback.call(ShareError.INTERNAL_ERROR); + } + } + + @Override + protected Boolean doInBackground() { + ArrayList<Uri> fileUris = new ArrayList<>(files.length); + ArrayList<BlobReceiver> blobReceivers = new ArrayList<>(files.length); + try { + File sharePath = ShareImageFileUtils.getSharedFilesDirectory(); + + if (!sharePath.exists() && !sharePath.mkdir()) { + throw new IOException("Failed to create directory for shared file."); + } + + for (int index = 0; index < files.length; ++index) { + File tempFile = File.createTempFile("share", + "." + FileUtils.getExtension(files[index].name), sharePath); + fileUris.add(ContentUriUtils.getContentUriFromFile(tempFile)); + blobReceivers.add(new BlobReceiver( + new FileOutputStream(tempFile), MAX_SHARED_FILE_BYTES)); + } + + } catch (IOException ie) { + Log.w(TAG, "Error creating shared file", ie); + return false; + } + + paramsBuilder.setFileContentType(SharedFileCollator.commonMimeType(files)); + paramsBuilder.setFileUris(fileUris); + SharedFileCollator collator = new SharedFileCollator(files.length, success -> { + if (success) { + mDelegate.share(paramsBuilder.build()); + } else { + callback.call(ShareError.INTERNAL_ERROR); + } + }); + + for (int index = 0; index < files.length; ++index) { + blobReceivers.get(index).start(files[index].blob.blob, collator); + } + return true; + } + }.executeOnTaskRunner(TASK_RUNNER); + } + + static boolean isDangerousFilename(String name) { + // Reject filenames without a permitted extension. + return name.indexOf('.') <= 0 + || !PERMITTED_EXTENSIONS.contains(FileUtils.getExtension(name)); + } + + static boolean isDangerousMimeType(String contentType) { + return !PERMITTED_MIME_TYPES.contains(contentType); + } + + @Nullable + private static Activity activityFromWebContents(@Nullable WebContents webContents) { + if (webContents == null) return null; + + WindowAndroid window = webContents.getTopLevelNativeWindow(); + if (window == null) return null; + + return window.getActivity().get(); + } +} diff --git a/chromium/components/browser_ui/webshare/android/java/src/org/chromium/components/browser_ui/webshare/ShareServiceImplTest.java b/chromium/components/browser_ui/webshare/android/java/src/org/chromium/components/browser_ui/webshare/ShareServiceImplTest.java new file mode 100644 index 00000000000..4c9d3359870 --- /dev/null +++ b/chromium/components/browser_ui/webshare/android/java/src/org/chromium/components/browser_ui/webshare/ShareServiceImplTest.java @@ -0,0 +1,84 @@ +// Copyright 2019 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.components.browser_ui.webshare; + +import androidx.test.filters.SmallTest; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; + +import org.chromium.base.test.BaseRobolectricTestRunner; + +/** + * Unit tests for {@link ShareServiceImpl}. + */ +@RunWith(BaseRobolectricTestRunner.class) +@Config(manifest = Config.NONE) +public class ShareServiceImplTest { + @Test + @SmallTest + public void testExtensionFormatting() { + Assert.assertFalse(ShareServiceImpl.isDangerousFilename("foo/bar.txt")); + Assert.assertFalse(ShareServiceImpl.isDangerousFilename("foo\\bar\u03C0.txt")); + Assert.assertTrue(ShareServiceImpl.isDangerousFilename("foo\\bar.tx\u03C0t")); + Assert.assertFalse(ShareServiceImpl.isDangerousFilename("https://example.com/a/b.html")); + Assert.assertTrue(ShareServiceImpl.isDangerousFilename("foo/bar.txt/")); + Assert.assertTrue(ShareServiceImpl.isDangerousFilename("foobar.tx\\t")); + Assert.assertTrue(ShareServiceImpl.isDangerousFilename("hello")); + Assert.assertTrue(ShareServiceImpl.isDangerousFilename("hellotxt")); + Assert.assertTrue(ShareServiceImpl.isDangerousFilename(".txt")); + Assert.assertFalse(ShareServiceImpl.isDangerousFilename("https://example.com/a/.txt")); + Assert.assertFalse(ShareServiceImpl.isDangerousFilename("/.txt")); + Assert.assertTrue(ShareServiceImpl.isDangerousFilename("..")); + Assert.assertTrue(ShareServiceImpl.isDangerousFilename(".hello.txt")); + } + + @Test + @SmallTest + public void testExecutable() { + Assert.assertTrue(ShareServiceImpl.isDangerousFilename("application.apk")); + Assert.assertTrue(ShareServiceImpl.isDangerousFilename("application.dex")); + Assert.assertTrue(ShareServiceImpl.isDangerousFilename("application.sh")); + } + + @Test + @SmallTest + public void testContent() { + Assert.assertFalse(ShareServiceImpl.isDangerousFilename("diagram.svg")); + Assert.assertFalse(ShareServiceImpl.isDangerousFilename("greeting.txt")); + Assert.assertFalse(ShareServiceImpl.isDangerousFilename("movie.mpeg")); + Assert.assertFalse(ShareServiceImpl.isDangerousFilename("photo.jpeg")); + Assert.assertFalse(ShareServiceImpl.isDangerousFilename("recording.wav")); + Assert.assertFalse(ShareServiceImpl.isDangerousFilename("statistics.csv")); + } + + @Test + @SmallTest + public void testCompound() { + Assert.assertFalse(ShareServiceImpl.isDangerousFilename("powerless.sh.txt")); + } + + @Test + @SmallTest + public void testUnsupportedMime() { + Assert.assertTrue(ShareServiceImpl.isDangerousMimeType("application/x-shockwave-flash")); + Assert.assertTrue(ShareServiceImpl.isDangerousMimeType("image/wmf")); + Assert.assertTrue(ShareServiceImpl.isDangerousMimeType("text/calendar")); + Assert.assertTrue(ShareServiceImpl.isDangerousMimeType("video/H264")); + } + + @Test + @SmallTest + public void testSupportedMime() { + Assert.assertFalse(ShareServiceImpl.isDangerousMimeType("audio/wav")); + Assert.assertFalse(ShareServiceImpl.isDangerousMimeType("image/jpeg")); + Assert.assertFalse(ShareServiceImpl.isDangerousMimeType("image/svg+xml")); + Assert.assertFalse(ShareServiceImpl.isDangerousMimeType("text/csv")); + Assert.assertFalse(ShareServiceImpl.isDangerousMimeType("text/plain")); + Assert.assertFalse(ShareServiceImpl.isDangerousMimeType("video/mpeg")); + } +} diff --git a/chromium/components/browser_ui/webshare/android/java/src/org/chromium/components/browser_ui/webshare/SharedFileCollator.java b/chromium/components/browser_ui/webshare/android/java/src/org/chromium/components/browser_ui/webshare/SharedFileCollator.java new file mode 100644 index 00000000000..268903ba59e --- /dev/null +++ b/chromium/components/browser_ui/webshare/android/java/src/org/chromium/components/browser_ui/webshare/SharedFileCollator.java @@ -0,0 +1,74 @@ +// Copyright 2019 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.components.browser_ui.webshare; + +import org.chromium.base.Callback; +import org.chromium.base.task.PostTask; +import org.chromium.content_public.browser.UiThreadTaskTraits; +import org.chromium.mojo.system.MojoResult; +import org.chromium.webshare.mojom.SharedFile; + +/** + * Initiates the share dialog when all files have been received. + */ +public class SharedFileCollator implements Callback<Integer> { + private static final String WILDCARD = "*/*"; + + private int mPending; + private Callback<Boolean> mCallback; + + /** + * Constructs a SharedFileCollator. + * + * @param params the share request to issue if blobs are successfully received. + * @param callback the callback to call if any blob is not successfully received. + */ + public SharedFileCollator(int pendingFileCount, Callback<Boolean> callback) { + mPending = pendingFileCount; + mCallback = callback; + + assert mPending > 0; + } + + /** + * Call with a MojoResult each time a blob has been received. + * + * @param result a MojoResult indicating if a blob was successfully received. + */ + @Override + public void onResult(final Integer result) { + if (mCallback == null) return; + + if (result == MojoResult.OK && --mPending > 0) return; + + final Callback<Boolean> callback = mCallback; + mCallback = null; + + PostTask.postTask( + UiThreadTaskTraits.DEFAULT, () -> { callback.onResult(result == MojoResult.OK); }); + } + + /** + * If the files have a common type and subtype, returns type / subtype + * Otherwise if the files have a common type, returns type / * + * Otherwise returns * / * + * + * @param files an array of files being shared. + */ + public static String commonMimeType(SharedFile[] files) { + if (files == null || files.length == 0) return WILDCARD; + String[] common = files[0].blob.contentType.split("/"); + if (common.length != 2) return WILDCARD; + for (int index = 1; index < files.length; ++index) { + String[] current = files[index].blob.contentType.split("/"); + if (current.length != 2) return WILDCARD; + if (!current[0].equals(common[0])) return WILDCARD; + if (!current[1].equals(common[1])) { + common[1] = "*"; + } + } + return common[0] + "/" + common[1]; + } +} diff --git a/chromium/components/browser_ui/webshare/android/java/src/org/chromium/components/browser_ui/webshare/SharedFileCollatorTest.java b/chromium/components/browser_ui/webshare/android/java/src/org/chromium/components/browser_ui/webshare/SharedFileCollatorTest.java new file mode 100644 index 00000000000..3d1e9a2ebf1 --- /dev/null +++ b/chromium/components/browser_ui/webshare/android/java/src/org/chromium/components/browser_ui/webshare/SharedFileCollatorTest.java @@ -0,0 +1,108 @@ +// Copyright 2019 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.components.browser_ui.webshare; + +import androidx.test.filters.SmallTest; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; + +import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.blink.mojom.SerializedBlob; +import org.chromium.webshare.mojom.SharedFile; + +/** + * Unit tests for {@link SharedFileCollator}. + */ +@RunWith(BaseRobolectricTestRunner.class) +@Config(manifest = Config.NONE) +public class SharedFileCollatorTest { + @Test + @SmallTest + public void testDissimilar() { + Assert.assertEquals("*/*", SharedFileCollator.commonMimeType(new SharedFile[0])); + Assert.assertEquals( + "*/*", SharedFileCollator.commonMimeType(createFiles("text/plain", "image/jpeg"))); + Assert.assertEquals("*/*", + SharedFileCollator.commonMimeType( + createFiles("video/mpeg", "video/ogg", "text/html"))); + } + + @Test + @SmallTest + public void testMalformed() { + Assert.assertEquals("*/*", SharedFileCollator.commonMimeType(createFiles("invalid"))); + Assert.assertEquals( + "*/*", SharedFileCollator.commonMimeType(createFiles("text/xml/svg", "text/xml"))); + Assert.assertEquals("*/*", + SharedFileCollator.commonMimeType(createFiles("image/webp", "image/webp/jpeg"))); + } + + @Test + @SmallTest + public void testApplication() { + Assert.assertEquals("application/*", + SharedFileCollator.commonMimeType( + createFiles("application/rtf", "application/x-bzip2"))); + } + + @Test + @SmallTest + public void testAudio() { + Assert.assertEquals("audio/*", + SharedFileCollator.commonMimeType(createFiles("audio/mp3", "audio/wav"))); + } + + @Test + @SmallTest + public void testImage() { + Assert.assertEquals( + "image/jpeg", SharedFileCollator.commonMimeType(createFiles("image/jpeg"))); + Assert.assertEquals("image/gif", + SharedFileCollator.commonMimeType( + createFiles("image/gif", "image/gif", "image/gif"))); + Assert.assertEquals("image/*", + SharedFileCollator.commonMimeType(createFiles("image/gif", "image/jpeg"))); + Assert.assertEquals("image/*", + SharedFileCollator.commonMimeType( + createFiles("image/gif", "image/gif", "image/jpeg"))); + } + + @Test + @SmallTest + public void testText() { + Assert.assertEquals("text/css", SharedFileCollator.commonMimeType(createFiles("text/css"))); + Assert.assertEquals( + "text/csv", SharedFileCollator.commonMimeType(createFiles("text/csv", "text/csv"))); + Assert.assertEquals("text/*", + SharedFileCollator.commonMimeType( + createFiles("text/csv", "text/html", "text/csv"))); + } + + @Test + @SmallTest + public void testVideo() { + Assert.assertEquals( + "video/webm", SharedFileCollator.commonMimeType(createFiles("video/webm"))); + Assert.assertEquals("video/*", + SharedFileCollator.commonMimeType(createFiles("video/mpeg", "video/webm"))); + Assert.assertEquals("video/*", + SharedFileCollator.commonMimeType( + createFiles("video/mpeg", "video/webm", "video/webm"))); + } + + private static SharedFile[] createFiles(String... mimeTypeList) { + SharedFile[] result = new SharedFile[mimeTypeList.length]; + for (int i = 0; i < mimeTypeList.length; ++i) { + SerializedBlob blob = new SerializedBlob(); + blob.contentType = mimeTypeList[i]; + result[i] = new SharedFile(); + result[i].blob = blob; + } + return result; + } +} diff --git a/chromium/components/browser_ui/widget/android/BUILD.gn b/chromium/components/browser_ui/widget/android/BUILD.gn index 2eaf6be1599..0d95a17fd7f 100644 --- a/chromium/components/browser_ui/widget/android/BUILD.gn +++ b/chromium/components/browser_ui/widget/android/BUILD.gn @@ -101,6 +101,7 @@ android_library("java") { "//components/embedder_support/android:util_java", "//third_party/android_deps:android_support_v4_java", "//third_party/android_deps:android_support_v7_appcompat_java", + "//third_party/android_deps:androidx_appcompat_appcompat_resources_java", "//third_party/android_deps:androidx_interpolator_interpolator_java", "//third_party/android_deps:androidx_recyclerview_recyclerview_java", "//ui/android:ui_java", @@ -235,9 +236,11 @@ android_library("javatests") { "//base:base_java_test_support", "//content/public/test/android:content_java_test_support", "//third_party/android_deps:androidx_appcompat_appcompat_java", + "//third_party/android_deps:androidx_appcompat_appcompat_resources_java", "//third_party/android_deps:androidx_core_core_java", "//third_party/android_support_test_runner:rules_java", "//third_party/android_support_test_runner:runner_java", + "//third_party/hamcrest:hamcrest_java", "//third_party/junit", "//ui/android:ui_java", "//ui/android:ui_java_test_support", @@ -284,5 +287,8 @@ java_library("junit") { "//base:base_java_test_support", "//base:base_junit_test_support", "//base/test:test_support_java", + "//third_party/android_deps:robolectric_all_java", + "//third_party/junit", + "//third_party/mockito:mockito_java", ] } diff --git a/chromium/components/browser_ui/widget/android/java/res/layout/promo_dialog_layout.xml b/chromium/components/browser_ui/widget/android/java/res/layout/promo_dialog_layout.xml index 7008991f559..1597e8a35b6 100644 --- a/chromium/components/browser_ui/widget/android/java/res/layout/promo_dialog_layout.xml +++ b/chromium/components/browser_ui/widget/android/java/res/layout/promo_dialog_layout.xml @@ -63,6 +63,7 @@ android:id="@+id/header" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:textDirection="locale" android:layout_marginTop="@dimen/dialog_header_margin" android:layout_marginBottom="@dimen/dialog_header_margin" android:textAppearance="@style/TextAppearance.Headline.Primary" /> @@ -71,6 +72,7 @@ android:id="@+id/subheader" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:textDirection="locale" app:leading="@dimen/text_size_medium_leading" style="@style/TextAppearance.TextMedium.Secondary" /> </org.chromium.components.browser_ui.widget.BoundedLinearLayout> diff --git a/chromium/components/browser_ui/widget/android/java/res/values/dimens.xml b/chromium/components/browser_ui/widget/android/java/res/values/dimens.xml index bb87b51078a..6b5699af985 100644 --- a/chromium/components/browser_ui/widget/android/java/res/values/dimens.xml +++ b/chromium/components/browser_ui/widget/android/java/res/values/dimens.xml @@ -16,7 +16,7 @@ <!-- Dialogs --> <dimen name="dialog_max_width">600dp</dimen> <dimen name="dialog_header_margin">14dp</dimen> - <dimen name="promo_dialog_illustration_margin">24dp</dimen> + <dimen name="promo_dialog_illustration_margin">8dp</dimen> <dimen name="promo_dialog_illustration_width">150dp</dimen> <dimen name="promo_dialog_padding">16dp</dimen> <dimen name="promo_dialog_stacked_margin">16dp</dimen> diff --git a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/DualControlLayoutTest.java b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/DualControlLayoutTest.java index 81d29b61223..3fb1559fe9e 100644 --- a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/DualControlLayoutTest.java +++ b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/DualControlLayoutTest.java @@ -7,7 +7,6 @@ package org.chromium.components.browser_ui.widget; import android.content.Context; import android.support.test.InstrumentationRegistry; import android.support.test.annotation.UiThreadTest; -import android.support.test.filters.SmallTest; import android.support.test.rule.UiThreadTestRule; import android.view.LayoutInflater; import android.view.View; @@ -17,6 +16,8 @@ import android.widget.Button; import android.widget.FrameLayout; import android.widget.Space; +import androidx.test.filters.SmallTest; + import org.junit.Assert; import org.junit.Before; import org.junit.Rule; diff --git a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/InsetObserverViewTest.java b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/InsetObserverViewTest.java index eec6e7e9303..f432e57c7fb 100644 --- a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/InsetObserverViewTest.java +++ b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/InsetObserverViewTest.java @@ -12,10 +12,11 @@ import static org.mockito.Mockito.verify; import android.app.Activity; import android.content.Context; import android.graphics.Rect; -import android.support.test.filters.SmallTest; import android.view.WindowInsets; import android.widget.LinearLayout; +import androidx.test.filters.SmallTest; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/MoreProgressButtonTest.java b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/MoreProgressButtonTest.java index 150fe66426f..80e15e276f3 100644 --- a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/MoreProgressButtonTest.java +++ b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/MoreProgressButtonTest.java @@ -8,13 +8,14 @@ import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; import android.app.Activity; -import android.support.test.filters.MediumTest; -import android.support.test.filters.SmallTest; import android.view.LayoutInflater; import android.view.View; import android.widget.FrameLayout; import android.widget.TextView; +import androidx.test.filters.MediumTest; +import androidx.test.filters.SmallTest; + import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/PromoDialog.java b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/PromoDialog.java index c7eb7c979bb..56cf042fdd9 100644 --- a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/PromoDialog.java +++ b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/PromoDialog.java @@ -50,6 +50,12 @@ public abstract class PromoDialog extends AlwaysDismissedDialog public int headerStringResource; /** + * Optional: CharSequence to show as promo title. + * This parameter takes precedence over {@link #headerStringResoruce} + */ + public CharSequence headerCharSequence; + + /** * Optional: CharSequence to show as descriptive text. * This parameter takes precedence over {@link #subheaderStringResoruce} */ @@ -67,6 +73,12 @@ public abstract class PromoDialog extends AlwaysDismissedDialog /** Optional: Resource ID of the String to show on the primary/ok button. */ public int primaryButtonStringResource; + /** + * Optional: CharSequence to show on the primary/ok button. + * This parameter takes precedence over {@link #primaryButtonStringResource} + */ + public CharSequence primaryButtonCharSequence; + /** Optional: Resource ID of the String to show on the secondary/cancel button. */ public int secondaryButtonStringResource; } @@ -74,7 +86,7 @@ public abstract class PromoDialog extends AlwaysDismissedDialog private static final int[] CLICKABLE_BUTTON_IDS = {R.id.button_primary, R.id.button_secondary}; private final FrameLayout mScrimView; - private final PromoDialogLayout mDialogLayout; + private PromoDialogLayout mDialogLayout; protected PromoDialog(Activity activity) { super(activity, R.style.PromoDialog); @@ -85,7 +97,6 @@ public abstract class PromoDialog extends AlwaysDismissedDialog LayoutInflater.from(activity).inflate(R.layout.promo_dialog_layout, mScrimView, true); mDialogLayout = (PromoDialogLayout) mScrimView.findViewById(R.id.promo_dialog_layout); - mDialogLayout.initialize(getDialogParams()); } /** @@ -112,6 +123,8 @@ public abstract class PromoDialog extends AlwaysDismissedDialog super.onCreate(savedInstanceState); setContentView(mScrimView); + mDialogLayout.initialize(getDialogParams()); + // Force the window to allow the dialog contents be as wide as necessary. getWindow().setLayout(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); diff --git a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/PromoDialogLayout.java b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/PromoDialogLayout.java index d9fc7165c1c..600212068de 100644 --- a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/PromoDialogLayout.java +++ b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/PromoDialogLayout.java @@ -81,8 +81,8 @@ public final class PromoDialogLayout extends BoundedLinearLayout { /** Initializes the dialog contents using the given params. Should only be called once. */ void initialize(DialogParams params) { assert mParams == null && params != null; - assert params.headerStringResource != 0; - assert params.primaryButtonStringResource != 0; + assert params.headerStringResource != 0 || params.headerCharSequence != null; + assert params.primaryButtonStringResource != 0 || params.primaryButtonCharSequence != null; mParams = params; if (mParams.drawableInstance != null) { @@ -99,7 +99,11 @@ public final class PromoDialogLayout extends BoundedLinearLayout { } // Create the header. - mHeaderView.setText(mParams.headerStringResource); + if (mParams.headerCharSequence != null) { + mHeaderView.setText(mParams.headerCharSequence); + } else { + mHeaderView.setText(mParams.headerStringResource); + } // Set up the subheader text. if (mParams.subheaderCharSequence != null) { @@ -124,7 +128,9 @@ public final class PromoDialogLayout extends BoundedLinearLayout { // Create the buttons. DualControlLayout buttonBar = (DualControlLayout) findViewById(R.id.button_bar); - String primaryString = getResources().getString(mParams.primaryButtonStringResource); + String primaryString = mParams.primaryButtonCharSequence != null + ? mParams.primaryButtonCharSequence.toString() + : getResources().getString(mParams.primaryButtonStringResource); buttonBar.addView( DualControlLayout.createButtonForLayout(getContext(), true, primaryString, null)); diff --git a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/PromoDialogTest.java b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/PromoDialogTest.java index df463c2ca1e..0246900b7d4 100644 --- a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/PromoDialogTest.java +++ b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/PromoDialogTest.java @@ -7,7 +7,6 @@ package org.chromium.components.browser_ui.widget; import android.app.Activity; import android.content.DialogInterface; import android.support.test.InstrumentationRegistry; -import android.support.test.filters.SmallTest; import android.text.method.LinkMovementMethod; import android.view.View; import android.view.View.MeasureSpec; @@ -16,6 +15,7 @@ import android.widget.LinearLayout; import android.widget.TextView; import androidx.core.view.ViewCompat; +import androidx.test.filters.SmallTest; import org.junit.Assert; import org.junit.Test; diff --git a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/RadioButtonLayoutTest.java b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/RadioButtonLayoutTest.java index 4c9eab9f127..c2ac17da022 100644 --- a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/RadioButtonLayoutTest.java +++ b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/RadioButtonLayoutTest.java @@ -7,12 +7,13 @@ package org.chromium.components.browser_ui.widget; import android.content.Context; import android.support.test.InstrumentationRegistry; import android.support.test.annotation.UiThreadTest; -import android.support.test.filters.SmallTest; import android.support.test.rule.UiThreadTestRule; import android.view.View; import android.view.ViewGroup.MarginLayoutParams; import android.widget.RadioButton; +import androidx.test.filters.SmallTest; + import org.junit.Assert; import org.junit.Before; import org.junit.Rule; diff --git a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/RadioButtonRenderTest.java b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/RadioButtonRenderTest.java index 9c379ac4673..54a2c38801e 100644 --- a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/RadioButtonRenderTest.java +++ b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/RadioButtonRenderTest.java @@ -6,10 +6,11 @@ package org.chromium.components.browser_ui.widget; import android.app.Activity; import android.graphics.Color; -import android.support.test.filters.SmallTest; import android.view.LayoutInflater; import android.view.View; +import androidx.test.filters.SmallTest; + import org.junit.Assert; import org.junit.Rule; import org.junit.Test; @@ -41,8 +42,7 @@ public class RadioButtonRenderTest extends DummyUiActivityTestCase { new NightModeTestUtils.NightModeParams().getParameters(); @Rule - public RenderTestRule mRenderTestRule = - new RenderTestRule("chrome/test/data/android/render_tests"); + public RenderTestRule mRenderTestRule = new RenderTestRule(); private RadioButtonWithDescriptionLayout mLayout; diff --git a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/RadioButtonWithDescriptionLayoutTest.java b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/RadioButtonWithDescriptionLayoutTest.java index abbb5974759..c831fb5f45d 100644 --- a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/RadioButtonWithDescriptionLayoutTest.java +++ b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/RadioButtonWithDescriptionLayoutTest.java @@ -7,7 +7,6 @@ package org.chromium.components.browser_ui.widget; import android.content.Context; import android.support.test.InstrumentationRegistry; import android.support.test.annotation.UiThreadTest; -import android.support.test.filters.SmallTest; import android.support.test.rule.UiThreadTestRule; import android.text.TextUtils; import android.view.LayoutInflater; @@ -16,6 +15,8 @@ import android.view.ViewGroup.MarginLayoutParams; import android.widget.EditText; import android.widget.TextView; +import androidx.test.filters.SmallTest; + import org.junit.Assert; import org.junit.Before; import org.junit.Rule; diff --git a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/RadioButtonWithEditTextTest.java b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/RadioButtonWithEditTextTest.java index 28e78008db2..66d0d8d9bfa 100644 --- a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/RadioButtonWithEditTextTest.java +++ b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/RadioButtonWithEditTextTest.java @@ -6,7 +6,6 @@ package org.chromium.components.browser_ui.widget; import android.app.Activity; import android.support.test.InstrumentationRegistry; -import android.support.test.filters.SmallTest; import android.text.InputType; import android.text.TextUtils; import android.view.KeyEvent; @@ -17,6 +16,9 @@ import android.widget.EditText; import android.widget.RadioButton; import android.widget.TextView; +import androidx.test.filters.SmallTest; + +import org.hamcrest.Matchers; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; @@ -266,14 +268,11 @@ public class RadioButtonWithEditTextTest extends DummyUiActivityTestCase { } private void assertIsKeyboardShowing(boolean isShowing) { - CriteriaHelper.pollUiThread( - new Criteria("Keyboard visibility does not consist with test setting.") { - @Override - public boolean isSatisfied() { - return KeyboardVisibilityDelegate.getInstance().isKeyboardShowing( - mActivity, mEditText) - == isShowing; - } - }); + CriteriaHelper.pollUiThread(() -> { + Criteria.checkThat("Keyboard visibility does not consist with test setting.", + KeyboardVisibilityDelegate.getInstance().isKeyboardShowing( + mActivity, mEditText), + Matchers.is(isShowing)); + }); } } diff --git a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/RoundedIconGeneratorTest.java b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/RoundedIconGeneratorTest.java index 4a20edde91b..8a7f4f809b5 100644 --- a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/RoundedIconGeneratorTest.java +++ b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/RoundedIconGeneratorTest.java @@ -7,7 +7,8 @@ package org.chromium.components.browser_ui.widget; import android.content.Context; import android.graphics.Color; import android.support.test.InstrumentationRegistry; -import android.support.test.filters.SmallTest; + +import androidx.test.filters.SmallTest; import org.junit.Assert; import org.junit.Before; diff --git a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/WrappingLayoutTest.java b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/WrappingLayoutTest.java index 2b5a03bc0af..854b7da4ad1 100644 --- a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/WrappingLayoutTest.java +++ b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/WrappingLayoutTest.java @@ -6,11 +6,11 @@ package org.chromium.components.browser_ui.widget; import android.content.Context; import android.support.test.InstrumentationRegistry; -import android.support.test.filters.SmallTest; -import android.util.LayoutDirection; import android.view.View; import android.view.View.MeasureSpec; +import androidx.test.filters.SmallTest; + import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -525,7 +525,7 @@ public class WrappingLayoutTest { ViewExpectation expectationB, ViewExpectation expectationC) { WrappingLayoutSubclass layout = WrappingLayoutSubclass.create( mContext, leftTopPadding, bottomRightPadding, spacing); - layout.setLayoutDirection(LayoutDirection.RTL); + layout.setLayoutDirection(View.LAYOUT_DIRECTION_RTL); layout.addTestViews(margin); layout.layoutAtSize(width, height, specWidth, specHeight, 0, 0); diff --git a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/highlight/ViewHighlighterTest.java b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/highlight/ViewHighlighterTest.java index 89022527e1a..1413dcca40a 100644 --- a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/highlight/ViewHighlighterTest.java +++ b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/highlight/ViewHighlighterTest.java @@ -8,11 +8,12 @@ import android.content.Context; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.support.test.InstrumentationRegistry; -import android.support.test.filters.MediumTest; import android.support.test.rule.UiThreadTestRule; import android.view.View; import android.widget.ImageView; +import androidx.test.filters.MediumTest; + import org.junit.Assert; import org.junit.Before; import org.junit.Rule; diff --git a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/image_tiles/TileCoordinatorImpl.java b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/image_tiles/TileCoordinatorImpl.java index bf599b35094..81e7e318a69 100644 --- a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/image_tiles/TileCoordinatorImpl.java +++ b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/image_tiles/TileCoordinatorImpl.java @@ -40,7 +40,7 @@ class TileCoordinatorImpl implements ImageTileCoordinator { for (int i = 0; i < mModel.size(); i++) { oldTiles.add(mModel.get(i)); } - boolean shouldAnimate = !oldTiles.isEmpty() && !oldTiles.equals(tiles); + boolean shouldAnimate = !oldTiles.isEmpty() && !tiles.isEmpty() && !oldTiles.equals(tiles); mModel.set(tiles); mView.scrollToBeginning(); diff --git a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/image_tiles/TileListView.java b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/image_tiles/TileListView.java index 9d1b4b8f2c2..4e7166f23f8 100644 --- a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/image_tiles/TileListView.java +++ b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/image_tiles/TileListView.java @@ -8,6 +8,8 @@ import android.content.Context; import android.content.res.Configuration; import android.graphics.Rect; import android.view.View; +import android.view.animation.Animation; +import android.view.animation.Animation.AnimationListener; import android.view.animation.AnimationUtils; import android.view.animation.LayoutAnimationController; @@ -58,7 +60,7 @@ class TileListView { mView.setItemAnimator(null); mLayoutAnimationController = AnimationUtils.loadLayoutAnimation(context, R.anim.image_grid_enter); - + configureAnimationListener(); mTileSizeSupplier = new TileSizeSupplier(context); PropertyModelChangeProcessor.create( @@ -86,7 +88,25 @@ class TileListView { * Called to show enter animation for the list items. */ void showAnimation(boolean animate) { - // TODO(shaktisahu): Fix animations. + if (animate) { + mView.setLayoutAnimation(mLayoutAnimationController); + mView.scheduleLayoutAnimation(); + } + } + + private void configureAnimationListener() { + mView.setLayoutAnimationListener(new AnimationListener() { + @Override + public void onAnimationStart(Animation animation) {} + + @Override + public void onAnimationEnd(Animation animation) { + mView.setLayoutAnimation(null); + } + + @Override + public void onAnimationRepeat(Animation animation) {} + }); } private class ItemDecorationImpl extends ItemDecoration { diff --git a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/listmenu/ListMenuRenderTest.java b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/listmenu/ListMenuRenderTest.java index 4fa1d04947c..ea9367e9b52 100644 --- a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/listmenu/ListMenuRenderTest.java +++ b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/listmenu/ListMenuRenderTest.java @@ -44,8 +44,7 @@ public class ListMenuRenderTest extends DummyUiActivityTestCase { new NightModeTestUtils.NightModeParams().getParameters(); @Rule - public RenderTestRule mRenderTestRule = - new RenderTestRule("chrome/test/data/android/render_tests"); + public RenderTestRule mRenderTestRule = new RenderTestRule(); private View mView; diff --git a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/promo/PromoCardCoordinatorTest.java b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/promo/PromoCardCoordinatorTest.java index 85bd7e6ac5d..be10a6832e7 100644 --- a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/promo/PromoCardCoordinatorTest.java +++ b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/promo/PromoCardCoordinatorTest.java @@ -7,10 +7,10 @@ package org.chromium.components.browser_ui.widget.promo; import android.content.Context; import android.graphics.drawable.Drawable; import android.support.test.InstrumentationRegistry; -import android.support.test.filters.SmallTest; import android.view.View; import androidx.appcompat.content.res.AppCompatResources; +import androidx.test.filters.SmallTest; import org.junit.Assert; import org.junit.Before; diff --git a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/promo/PromoCardImpressionTest.java b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/promo/PromoCardImpressionTest.java index 871b0594c6c..a911afaf2bf 100644 --- a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/promo/PromoCardImpressionTest.java +++ b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/promo/PromoCardImpressionTest.java @@ -5,11 +5,12 @@ package org.chromium.components.browser_ui.widget.promo; import android.app.Activity; -import android.support.test.filters.SmallTest; import android.view.View; import android.view.ViewGroup.LayoutParams; import android.widget.FrameLayout; +import androidx.test.filters.SmallTest; + import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/promo/PromoCardViewRenderTest.java b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/promo/PromoCardViewRenderTest.java index 34c2aa3763e..857f5cd03b9 100644 --- a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/promo/PromoCardViewRenderTest.java +++ b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/promo/PromoCardViewRenderTest.java @@ -6,14 +6,15 @@ package org.chromium.components.browser_ui.widget.promo; import android.app.Activity; import android.graphics.drawable.Drawable; -import android.support.test.filters.SmallTest; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.LinearLayout.LayoutParams; import androidx.appcompat.content.res.AppCompatResources; +import androidx.test.filters.SmallTest; +import org.hamcrest.Matchers; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -33,7 +34,6 @@ import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.test.util.DummyUiActivityTestCase; import org.chromium.ui.test.util.NightModeTestUtils; import org.chromium.ui.test.util.RenderTestRule; -import org.chromium.ui.widget.ButtonCompat; import java.util.List; @@ -48,8 +48,7 @@ public class PromoCardViewRenderTest extends DummyUiActivityTestCase { new NightModeTestUtils.NightModeParams().getParameters(); @Rule - public RenderTestRule mRenderTestRule = - new RenderTestRule("chrome/test/data/android/render_tests"); + public RenderTestRule mRenderTestRule = new RenderTestRule(); public PromoCardViewRenderTest(boolean nightModeEnabled) { NightModeTestUtils.setUpNightModeForDummyUiActivity(nightModeEnabled); @@ -110,11 +109,12 @@ public class PromoCardViewRenderTest extends DummyUiActivityTestCase { mModel.set(PromoCardProperties.HAS_SECONDARY_BUTTON, false); setPromoCard(LayoutStyle.LARGE); - CriteriaHelper.pollUiThread(Criteria.equals(View.GONE, () -> { - ButtonCompat secondaryButton = - mPromoCardCoordinator.getView().findViewById(R.id.promo_secondary_button); - return secondaryButton.getVisibility(); - })); + CriteriaHelper.pollUiThread(() -> { + int visibility = mPromoCardCoordinator.getView() + .findViewById(R.id.promo_secondary_button) + .getVisibility(); + Criteria.checkThat(visibility, Matchers.is(View.GONE)); + }); mRenderTestRule.render(mPromoCardCoordinator.getView(), "promo_card_secondary_hidden"); } diff --git a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/scrim/ScrimTest.java b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/scrim/ScrimTest.java index 95dea15976a..6f01c2aa11a 100644 --- a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/scrim/ScrimTest.java +++ b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/scrim/ScrimTest.java @@ -13,13 +13,14 @@ import static org.junit.Assert.assertTrue; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; -import android.support.test.filters.SmallTest; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; import androidx.annotation.ColorInt; +import androidx.test.filters.SmallTest; +import org.hamcrest.Matchers; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -30,6 +31,7 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.Feature; +import org.chromium.content_public.browser.test.util.Criteria; import org.chromium.content_public.browser.test.util.CriteriaHelper; import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.test.util.DummyUiActivityTestCase; @@ -103,10 +105,10 @@ public class ScrimTest extends DummyUiActivityTestCase { ThreadUtils.runOnUiThreadBlocking(() -> mScrimCoordinator.hideScrim(false)); - CriteriaHelper.pollUiThread(() - -> mScrimCoordinator.getViewForTesting() == null, - "Scrim should be null after being hidden.", CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL, - CriteriaHelper.DEFAULT_POLLING_INTERVAL); + CriteriaHelper.pollUiThread(() -> { + Criteria.checkThat("Scrim should be null after being hidden.", + mScrimCoordinator.getViewForTesting(), Matchers.nullValue()); + }); } @Test @@ -215,10 +217,10 @@ public class ScrimTest extends DummyUiActivityTestCase { ThreadUtils.runOnUiThreadBlocking(() -> mScrimCoordinator.hideScrim(false)); - CriteriaHelper.pollUiThread(() - -> mScrimCoordinator.getViewForTesting() == null, - "Scrim should be null after being hidden.", CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL, - CriteriaHelper.DEFAULT_POLLING_INTERVAL); + CriteriaHelper.pollUiThread(() -> { + Criteria.checkThat("Scrim should be null after being hidden.", + mScrimCoordinator.getViewForTesting(), Matchers.nullValue()); + }); } @Test diff --git a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/text/AlertDialogEditText.java b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/text/AlertDialogEditText.java index 9cffe2c5911..9620c8fad8b 100644 --- a/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/text/AlertDialogEditText.java +++ b/chromium/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/text/AlertDialogEditText.java @@ -4,70 +4,50 @@ package org.chromium.components.browser_ui.widget.text; +import android.annotation.SuppressLint; import android.content.Context; -import android.graphics.PorterDuff; -import android.graphics.drawable.Drawable; -import android.os.Build; +import android.text.TextUtils; import android.util.AttributeSet; -import android.view.ActionMode; -import android.view.Menu; -import android.view.MenuItem; +import android.view.ViewStructure; import android.widget.EditText; import androidx.appcompat.widget.AppCompatEditText; import org.chromium.base.ApiCompatibilityUtils; -import org.chromium.components.browser_ui.widget.R; +import org.chromium.base.annotations.VerifiesOnO; /** - * EditText to use in AlertDialog needed due to b/20882793 and b/122113958. This class should be - * removed when we roll to AppCompat with a fix for both issues. + * Wrapper class needed due to b/122113958. * * Note that for password fields the hint text is expected to be set in XML so that it is available - * during inflation. If the hint text or content description is changed programatically, consider + * during inflation. If the hint text or content description is changed programmatically, consider * calling {@link ApiCompatibilityUtils#setPasswordEditTextContentDescription(EditText)} after * the change. */ +@VerifiesOnO public class AlertDialogEditText extends AppCompatEditText { + private String mUrl; + public AlertDialogEditText(Context context, AttributeSet attrs) { super(context, attrs); } + public void setUrl(String url) { + mUrl = url; + } + @Override protected void onFinishInflate() { super.onFinishInflate(); - ApiCompatibilityUtils.setPasswordEditTextContentDescription(this); + } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) return; - - setCustomSelectionActionModeCallback(new ActionMode.Callback() { - @Override - public boolean onPrepareActionMode(ActionMode mode, Menu menu) { - return true; - } - - @Override - public void onDestroyActionMode(ActionMode mode) {} - - @Override - public boolean onCreateActionMode(ActionMode mode, Menu menu) { - for (int i = 0; i < menu.size(); i++) { - MenuItem item = menu.getItem(i); - Drawable icon = item.getIcon(); - if (icon == null) break; - icon.setColorFilter(ApiCompatibilityUtils.getColor( - getResources(), R.color.default_icon_color), - PorterDuff.Mode.SRC_IN); - item.setIcon(icon); - } - return true; - } - - @Override - public boolean onActionItemClicked(ActionMode mode, MenuItem item) { - return false; - } - }); + @Override + @SuppressLint("NewApi") + public void onProvideAutofillStructure(ViewStructure structure, int flags) { + if (!TextUtils.isEmpty(mUrl)) { + structure.setWebDomain(mUrl); + } + super.onProvideAutofillStructure(structure, flags); } } |