Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve the game's archive, achievements, and ranking functions #2576

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions play-services-auth-base/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,6 @@ dependencies {
api project(':play-services-basement')
api project(':play-services-base')
api project(':play-services-tasks')

annotationProcessor project(':safe-parcel-processor')
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* SPDX-FileCopyrightText: 2024 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/

package org.microg.gms.utils

import android.graphics.Bitmap
import kotlin.math.sqrt

object BitmapUtils {

fun getBitmapSize(bitmap: Bitmap?): Int {
if (bitmap != null) {
return bitmap.height * bitmap.rowBytes
}
return 0
}

fun scaledBitmap(bitmap: Bitmap, maxSize: Float): Bitmap {
val height: Int = bitmap.getHeight()
val width: Int = bitmap.getWidth()
val sqrt =
sqrt(((maxSize) / ((width.toFloat()) / (height.toFloat()) * ((bitmap.getRowBytes() / width).toFloat()))).toDouble())
.toInt()
return Bitmap.createScaledBitmap(
bitmap,
(((sqrt.toFloat()) / (height.toFloat()) * (width.toFloat())).toInt()),
sqrt,
true
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,28 @@
package com.google.android.gms.common.images;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.widget.ImageView;

import androidx.annotation.NonNull;
import androidx.annotation.WorkerThread;
import androidx.collection.LruCache;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
* This class is used to load images from the network and handles local caching for you.
Expand All @@ -21,6 +43,157 @@ public class ImageManager {
* @return A new ImageManager.
*/
public static ImageManager create(Context context) {
throw new UnsupportedOperationException();
if (INSTANCE == null) {
synchronized (ImageManager.class) {
if (INSTANCE == null) {
INSTANCE = new ImageManager(context);
}
}
}
return INSTANCE;
}

public static final String TAG = "ImageManager";
private static volatile ImageManager INSTANCE;
private final LruCache<String, Bitmap> memoryCache;
private final ExecutorService executorService;
private final Handler handler;
private final Context context;

private ImageManager(Context context) {
this.context = context.getApplicationContext();
this.handler = new Handler(Looper.getMainLooper());
this.executorService = Executors.newFixedThreadPool(4);

final int cacheSize = (int) (Runtime.getRuntime().maxMemory() / 1024 / 8);
this.memoryCache = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(@NonNull String key, @NonNull Bitmap bitmap) {
return bitmap.getByteCount() / 1024;
}
};
}

/**
* Compress Bitmap
*/
public byte[] compressBitmap(Bitmap bitmap, Bitmap.CompressFormat format, int quality) {
Log.d(TAG, "compressBitmap width: " + bitmap.getWidth() + " height:" + bitmap.getHeight());
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(format, quality, byteArrayOutputStream);
byte[] bitmapBytes = byteArrayOutputStream.toByteArray();
bitmap = BitmapFactory.decodeByteArray(bitmapBytes, 0, bitmapBytes.length);
Log.d(TAG, "compressBitmap compress width: " + bitmap.getWidth() + " height:" + bitmap.getHeight());
return bitmapBytes;
}

public byte[] compressBitmap(Bitmap original, int newWidth, int newHeight) {
Log.d(TAG, "compressBitmap width: " + original.getWidth() + " height:" + original.getHeight());
Bitmap target = Bitmap.createScaledBitmap(original, newWidth, newHeight, true);
Log.d(TAG, "compressBitmap target width: " + target.getWidth() + " height:" + target.getHeight());
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
target.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);
return byteArrayOutputStream.toByteArray();
}

public void loadImage(final String url, final ImageView imageView) {
if (imageView == null) {
Log.d(TAG, "loadImage: imageView is null");
return;
}
final Bitmap cachedBitmap = getBitmapFromCache(url);
if (cachedBitmap != null) {
Log.d(TAG, "loadImage from cached");
imageView.setImageBitmap(cachedBitmap);
} else {
Log.d(TAG, "loadImage from net");
imageView.setTag(url);
executorService.submit(() -> {
final Bitmap bitmap = downloadBitmap(url);
if (bitmap != null) {
addBitmapToCache(url, bitmap);
if (imageView.getTag().equals(url)) {
handler.post(() -> imageView.setImageBitmap(bitmap));
}
}
});
}
}

private Bitmap getBitmapFromCache(String key) {
Bitmap bitmap = memoryCache.get(key);
if (bitmap == null) {
bitmap = getBitmapFromDiskCache(key);
}
return bitmap;
}

private void addBitmapToCache(String key, Bitmap bitmap) {
if (getBitmapFromCache(key) == null) {
memoryCache.put(key, bitmap);
addBitmapToDiskCache(key, bitmap);
}
}

private Bitmap getBitmapFromDiskCache(String key) {
File file = getDiskCacheFile(key);
if (file.exists()) {
return BitmapFactory.decodeFile(file.getAbsolutePath());
}
return null;
}

private void addBitmapToDiskCache(String key, Bitmap bitmap) {
File file = getDiskCacheFile(key);
try (FileOutputStream outputStream = new FileOutputStream(file)) {
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
} catch (IOException e) {
Log.e(TAG, "addBitmapToDiskCache: ", e);
}
}

private File getDiskCacheFile(String key) {
File cacheDir = context.getCacheDir();
return new File(cacheDir, md5(key));
}

private String md5(String s) {
try {
MessageDigest digest = MessageDigest.getInstance("MD5");
digest.update(s.getBytes());
byte[] messageDigest = digest.digest();
StringBuilder hexString = new StringBuilder();
for (byte b : messageDigest) {
StringBuilder h = new StringBuilder(Integer.toHexString(0xFF & b));
while (h.length() < 2) h.insert(0, "0");
hexString.append(h);
}
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
Log.e(TAG, "md5: ", e);
}
return "";
}

@WorkerThread
private Bitmap downloadBitmap(String url) {
HttpURLConnection connection = null;
try {
connection = (HttpURLConnection) new URL(url).openConnection();
connection.connect();
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
InputStream inputStream = connection.getInputStream();
return BitmapFactory.decodeStream(inputStream);
}
} catch (IOException e) {
Log.d(TAG, "downloadBitmap: ", e);
} finally {
if (connection != null) {
connection.disconnect();
}
}
return null;
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* SPDX-FileCopyrightText: 2024 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.common.util;

import android.os.ParcelFileDescriptor;

import androidx.annotation.NonNull;

import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public final class IOUtils {
private IOUtils() {
}

public static void closeQuietly(ParcelFileDescriptor parcelFileDescriptor) {
if (parcelFileDescriptor != null) {
try {
parcelFileDescriptor.close();
} catch (IOException unused) {
}
}
}

public static long copyStream(@NonNull InputStream inputStream, @NonNull OutputStream outputStream) throws IOException {
return copyStream(inputStream, outputStream, false, 1024);
}

public static boolean isGzipByteBuffer(@NonNull byte[] bArr) {
if (bArr.length > 1) {
if ((((bArr[1] & 255) << 8) | (bArr[0] & 255)) == 35615) {
return true;
}
}
return false;
}

public static byte[] readInputStreamFully(@NonNull InputStream inputStream) throws IOException {
return readInputStreamFully(inputStream, true);
}

public static byte[] toByteArray(@NonNull InputStream inputStream) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] bArr = new byte[4096];
while (true) {
int read = inputStream.read(bArr);
if (read == -1) {
return byteArrayOutputStream.toByteArray();
}
byteArrayOutputStream.write(bArr, 0, read);
}
}


public static void closeQuietly(Closeable closeable) {
if (closeable != null) {
try {
closeable.close();
} catch (IOException unused) {
}
}
}

public static long copyStream(@NonNull InputStream inputStream, @NonNull OutputStream outputStream, boolean z, int i) throws IOException {
byte[] bArr = new byte[i];
long j = 0;
while (true) {
try {
int read = inputStream.read(bArr, 0, i);
if (read == -1) {
break;
}
j += read;
outputStream.write(bArr, 0, read);
} catch (Throwable th) {
if (z) {
closeQuietly(inputStream);
closeQuietly(outputStream);
}
throw th;
}
}
if (z) {
closeQuietly(inputStream);
closeQuietly(outputStream);
}
return j;
}

public static byte[] readInputStreamFully(@NonNull InputStream inputStream, boolean z) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
copyStream(inputStream, byteArrayOutputStream, z, 1024);
return byteArrayOutputStream.toByteArray();
}

}
1 change: 1 addition & 0 deletions play-services-core-proto/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ apply plugin: 'kotlin'

dependencies {
implementation "com.squareup.wire:wire-runtime:$wireVersion"
api "com.squareup.wire:wire-grpc-client:$wireVersion"
}

wire {
Expand Down
Loading