pt 1 in reviving the android build (copied from pm 28a1, wish me luck)

This commit is contained in:
wuggy 2026-04-08 15:43:25 -07:00
commit d7788a6d6d
4249 changed files with 468189 additions and 0 deletions

View file

@ -0,0 +1,44 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.util;
import android.graphics.Color;
public class ColorUtil {
public static int darken(final int color, final double fraction) {
int red = Color.red(color);
int green = Color.green(color);
int blue = Color.blue(color);
red = darkenColor(red, fraction);
green = darkenColor(green, fraction);
blue = darkenColor(blue, fraction);
final int alpha = Color.alpha(color);
return Color.argb(alpha, red, green, blue);
}
public static int getReadableTextColor(final int backgroundColor) {
final int greyValue = grayscaleFromRGB(backgroundColor);
// 186 chosen rather than the seemingly obvious 128 because of gamma.
if (greyValue < 186) {
return Color.WHITE;
} else {
return Color.BLACK;
}
}
private static int darkenColor(final int color, final double fraction) {
return (int) Math.max(color - (color * fraction), 0);
}
private static int grayscaleFromRGB(final int color) {
final int red = Color.red(color);
final int green = Color.green(color);
final int blue = Color.blue(color);
// Magic weighting taken from a stackoverflow post, supposedly related to how
// humans perceive color.
return (int) (0.299 * red + 0.587 * green + 0.114 * blue);
}
}

View file

@ -0,0 +1,66 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.util;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.drawable.Drawable;
import android.support.annotation.CheckResult;
import android.support.annotation.ColorInt;
import android.support.annotation.ColorRes;
import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
import android.support.v4.graphics.drawable.DrawableCompat;
import org.mozilla.gecko.AppConstants;
public class DrawableUtil {
/**
* Tints the given drawable with the given color and returns it.
*/
@CheckResult
public static Drawable tintDrawable(@NonNull final Context context,
@DrawableRes final int drawableID,
@ColorInt final int color) {
final Drawable icon = DrawableCompat.wrap(ResourceDrawableUtils.getDrawable(context, drawableID)
.mutate());
DrawableCompat.setTint(icon, color);
return icon;
}
/**
* Tints the given drawable with the given color and returns it.
*/
@CheckResult
public static Drawable tintDrawableWithColorRes(@NonNull final Context context,
@DrawableRes final int drawableID,
@ColorRes final int colorID) {
return tintDrawable(context, drawableID, ContextCompat.getColor(context, colorID));
}
/**
* Tints the given drawable with the given tint list and returns it. Note that you
* should no longer use the argument Drawable because the argument is not mutated
* on pre-Lollipop devices but is mutated on L+ due to differences in the Support
* Library implementation (bug 1193950).
*/
@CheckResult
public static Drawable tintDrawableWithStateList(@NonNull final Drawable drawable,
@NonNull final ColorStateList colorList) {
final Drawable wrappedDrawable = DrawableCompat.wrap(drawable.mutate());
DrawableCompat.setTintList(wrappedDrawable, colorList);
// DrawableCompat on pre-L doesn't handle its bounds correctly, and by default therefore won't
// be rendered - we need to manually copy the bounds as a workaround:
if (AppConstants.Versions.preMarshmallow) {
wrappedDrawable.setBounds(0, 0, wrappedDrawable.getIntrinsicHeight(), wrappedDrawable.getIntrinsicHeight());
}
return wrappedDrawable;
}
}

View file

@ -0,0 +1,136 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.util;
import android.content.Context;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull;
import android.support.v7.widget.AppCompatDrawableManager;
import android.text.TextUtils;
import android.util.Log;
import org.mozilla.gecko.util.GeckoJarReader;
import org.mozilla.gecko.util.ThreadUtils;
import org.mozilla.gecko.util.UIAsyncTask;
import java.io.InputStream;
import java.net.URL;
import static org.mozilla.gecko.gfx.BitmapUtils.getBitmapFromDataURI;
import static org.mozilla.gecko.gfx.BitmapUtils.getResource;
public class ResourceDrawableUtils {
private static final String LOGTAG = "ResourceDrawableUtils";
public static Drawable getDrawable(@NonNull final Context context,
@DrawableRes final int drawableID) {
// TODO: upgrade this call to use AppCompatResources when upgrading to support library >= 24.2
// https://developer.android.com/reference/android/support/v7/content/res/AppCompatResources.html#getDrawable(android.content.Context,%20int)
return AppCompatDrawableManager.get().getDrawable(context, drawableID);
}
public interface BitmapLoader {
public void onBitmapFound(Drawable d);
}
public static void runOnBitmapFoundOnUiThread(final BitmapLoader loader, final Drawable d) {
if (ThreadUtils.isOnUiThread()) {
loader.onBitmapFound(d);
return;
}
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
loader.onBitmapFound(d);
}
});
}
/**
* Attempts to find a drawable associated with a given string, using its URI scheme to determine
* how to load the drawable. The BitmapLoader's `onBitmapFound` method is always called, and
* will be called with `null` if no drawable is found.
*
* The BitmapLoader `onBitmapFound` method always runs on the UI thread.
*/
public static void getDrawable(final Context context, final String data, final BitmapLoader loader) {
if (TextUtils.isEmpty(data)) {
runOnBitmapFoundOnUiThread(loader, null);
return;
}
if (data.startsWith("data")) {
final BitmapDrawable d = new BitmapDrawable(context.getResources(), getBitmapFromDataURI(data));
runOnBitmapFoundOnUiThread(loader, d);
return;
}
if (data.startsWith("jar:") || data.startsWith("file://")) {
(new UIAsyncTask.WithoutParams<Drawable>(ThreadUtils.getBackgroundHandler()) {
@Override
public Drawable doInBackground() {
try {
if (data.startsWith("jar:jar")) {
return GeckoJarReader.getBitmapDrawable(
context, context.getResources(), data);
}
// Don't attempt to validate the JAR signature when loading an add-on icon
if (data.startsWith("jar:file")) {
return GeckoJarReader.getBitmapDrawable(
context, context.getResources(), Uri.decode(data));
}
final URL url = new URL(data);
final InputStream is = (InputStream) url.getContent();
try {
return Drawable.createFromStream(is, "src");
} finally {
is.close();
}
} catch (Exception e) {
Log.w(LOGTAG, "Unable to set icon", e);
}
return null;
}
@Override
public void onPostExecute(Drawable drawable) {
loader.onBitmapFound(drawable);
}
}).execute();
return;
}
if (data.startsWith("-moz-icon://")) {
final Uri imageUri = Uri.parse(data);
final String ssp = imageUri.getSchemeSpecificPart();
final String resource = ssp.substring(ssp.lastIndexOf('/') + 1);
try {
final Drawable d = context.getPackageManager().getApplicationIcon(resource);
runOnBitmapFoundOnUiThread(loader, d);
} catch (Exception ex) { }
return;
}
if (data.startsWith("drawable://")) {
final Uri imageUri = Uri.parse(data);
final int id = getResource(context, imageUri);
final Drawable d = getDrawable(context, id);
runOnBitmapFoundOnUiThread(loader, d);
return;
}
runOnBitmapFoundOnUiThread(loader, null);
}
}

View file

@ -0,0 +1,48 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.util;
import android.graphics.Rect;
import android.view.TouchDelegate;
import android.view.View;
import org.mozilla.gecko.R;
public class TouchTargetUtil {
/**
* Ensures that a given targetView has a large enough touch area to ensure it can be selected.
* A TouchDelegate will be added to the enclosingView as necessary.
*
* @param targetView
* @param enclosingView
*/
public static void ensureTargetHitArea(final View targetView, final View enclosingView) {
enclosingView.post(new Runnable() {
@Override
public void run() {
Rect delegateArea = new Rect();
targetView.getHitRect(delegateArea);
final int targetHitArea = enclosingView.getContext().getResources().getDimensionPixelSize(R.dimen.touch_target_size);
final int widthDelta = (targetHitArea - delegateArea.width()) / 2;
delegateArea.right += widthDelta;
delegateArea.left -= widthDelta;
final int heightDelta = (targetHitArea - delegateArea.height()) / 2;
delegateArea.bottom += heightDelta;
delegateArea.top -= heightDelta;
if (heightDelta <= 0 && widthDelta <= 0) {
return;
}
TouchDelegate touchDelegate = new TouchDelegate(delegateArea, targetView);
enclosingView.setTouchDelegate(touchDelegate);
}
});
}
}

View file

@ -0,0 +1,128 @@
package org.mozilla.gecko.util;
import org.mozilla.gecko.R;
/**
* (linter: UnusedResources) We use resources in places Android Lint can't check (e.g. JS) - this is
* a set of those references so Android Lint stops complaining.
*/
@SuppressWarnings("unused")
final class UnusedResourcesUtil {
public static final int[] CONSTANTS = {
R.dimen.match_parent,
R.dimen.wrap_content,
};
public static final int[] USED_IN_BRANDING = {
R.drawable.large_icon
};
public static final int[] USED_IN_COLOR_PALETTE = {
R.color.private_browsing_purple, // This will be used eventually, then this item removed.
};
public static final int[] USED_IN_CRASH_REPORTER = {
R.string.crash_allow_contact2,
R.string.crash_close_label,
R.string.crash_comment,
R.string.crash_email,
R.string.crash_include_url2,
R.string.crash_message2,
R.string.crash_restart_label,
R.string.crash_send_report_message3,
R.string.crash_sorry,
};
public static final int[] USED_IN_JS = {
R.drawable.ab_search,
R.drawable.alert_camera,
R.drawable.alert_download,
R.drawable.alert_download_animation,
R.drawable.alert_mic,
R.drawable.alert_mic_camera,
R.drawable.casting,
R.drawable.casting_active,
R.drawable.close,
R.drawable.homepage_banner_firstrun,
R.drawable.icon_openinapp,
R.drawable.pause,
R.drawable.phone,
R.drawable.play,
R.drawable.reader,
R.drawable.reader_active,
R.drawable.sync_promo,
R.drawable.undo_button_icon,
};
public static final int[] USED_IN_MANIFEST = {
R.drawable.search_launcher,
R.string.crash_reporter_title,
R.xml.fxaccount_authenticator,
R.xml.fxaccount_syncadapter,
R.xml.search_widget_info,
R.xml.searchable,
};
public static final int[] USED_IN_SUGGESTEDSITES = {
R.drawable.suggestedsites_amazon,
R.drawable.suggestedsites_facebook,
R.drawable.suggestedsites_restricted_fxsupport,
R.drawable.suggestedsites_restricted_mozilla,
R.drawable.suggestedsites_twitter,
R.drawable.suggestedsites_webmaker,
R.drawable.suggestedsites_wikipedia,
R.drawable.suggestedsites_youtube,
};
public static final int[] USED_IN_BOOKMARKDEFAULTS = {
R.raw.bookmarkdefaults_favicon_addons,
R.raw.bookmarkdefaults_favicon_support,
R.raw.bookmarkdefaults_favicon_restricted_support,
R.raw.bookmarkdefaults_favicon_restricted_webmaker,
R.string.bookmarkdefaults_title_restricted_support,
R.string.bookmarkdefaults_url_restricted_support,
R.string.bookmarkdefaults_title_restricted_webmaker,
R.string.bookmarkdefaults_url_restricted_webmaker,
};
public static final int[] USED_IN_PREFS = {
R.xml.preferences_advanced,
R.xml.preferences_accessibility,
R.xml.preferences_home,
R.xml.preferences_privacy,
R.xml.preferences_privacy_clear_tablet,
R.xml.preferences_default_browser_tablet
};
// We are migrating to Gradle 2.10 and the Android Gradle plugin 2.0. The new plugin does find
// more unused resources but we are not ready to remove them yet. Some of the resources are going
// to be reused soon. This is a temporary solution so that the gradle migration is not blocked.
// See bug 1263390 / bug 1268414.
public static final int[] TEMPORARY_UNUSED_WHILE_MIGRATING_GRADLE = {
R.color.remote_tabs_setup_button_background_hit,
R.drawable.remote_tabs_setup_button_background,
R.style.TabsPanelSectionBase,
R.style.TabsPanelSection,
R.style.TabsPanelItemBase,
R.style.TabsPanelItem,
R.style.TabsPanelItem_TextAppearance,
R.style.TabsPanelItem_TextAppearance_Header,
R.style.TabsPanelItem_TextAppearance_Linkified,
R.style.TabWidget,
R.style.GeckoDialogTitle,
R.style.GeckoDialogTitle_SubTitle,
R.style.RemoteTabsPanelItem,
R.style.RemoteTabsPanelItem_TextAppearance,
R.style.RemoteTabsPanelItem_TextAppearance_Header,
R.style.RemoteTabsPanelItem_TextAppearance_Linkified,
R.style.RemoteTabsPanelItem_Button,
};
// String resources that are used in the full-pane Activity Stream that are temporarily
// not needed while Activity Stream is part of the HomePager
public static final int[] TEMPORARY_UNUSED_ACTIVITY_STREAM = {
R.string.activity_stream_topsites
};
}

View file

@ -0,0 +1,33 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.util;
import android.content.res.TypedArray;
import android.view.View;
import org.mozilla.gecko.AppConstants;
import org.mozilla.gecko.R;
public class ViewUtil {
/**
* Enable a circular touch ripple for a given view. This is intended for borderless views,
* such as (3-dot) menu buttons.
*
* Because of platform limitations a square ripple is used on Android 4.
*/
public static void enableTouchRipple(View view) {
final TypedArray backgroundDrawableArray;
if (AppConstants.Versions.feature21Plus) {
backgroundDrawableArray = view.getContext().obtainStyledAttributes(new int[] { R.attr.selectableItemBackgroundBorderless });
} else {
backgroundDrawableArray = view.getContext().obtainStyledAttributes(new int[] { R.attr.selectableItemBackground });
}
// This call is deprecated, but the replacement setBackground(Drawable) isn't available
// until API 16.
view.setBackgroundDrawable(backgroundDrawableArray.getDrawable(0));
}
}