lineage-compat: Import all utility classes from lineage-sdk
* Most device modules like doze only depend on these
* Exclude ActionUtils, DeviceKeyConstants, LineageLockPatternUtils, PowerMenuUtils
Change-Id: Id9b5e3d81bd4ac00dbe8a3c5beb8b7373bbc4774
diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..40a1d2a
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,21 @@
+//
+// Copyright (C) 2022 The LeafOS Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+java_library {
+ name: "org.lineageos.platform.internal",
+
+ srcs: ["src/**/*.java"],
+}
diff --git a/src/org/lineageos/internal/util/FileUtils.java b/src/org/lineageos/internal/util/FileUtils.java
new file mode 100644
index 0000000..efe6071
--- /dev/null
+++ b/src/org/lineageos/internal/util/FileUtils.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2016 The CyanogenMod Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.lineageos.internal.util;
+
+import android.util.Log;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+
+public final class FileUtils {
+ private static final String TAG = "FileUtils";
+
+ private FileUtils() {
+ // This class is not supposed to be instantiated
+ }
+
+ /**
+ * Reads the first line of text from the given file.
+ * Reference {@link BufferedReader#readLine()} for clarification on what a line is
+ *
+ * @return the read line contents, or null on failure
+ */
+ public static String readOneLine(String fileName) {
+ String line = null;
+ BufferedReader reader = null;
+
+ try {
+ reader = new BufferedReader(new FileReader(fileName), 512);
+ line = reader.readLine();
+ } catch (FileNotFoundException e) {
+ Log.w(TAG, "No such file " + fileName + " for reading", e);
+ } catch (IOException e) {
+ Log.e(TAG, "Could not read from file " + fileName, e);
+ } finally {
+ try {
+ if (reader != null) {
+ reader.close();
+ }
+ } catch (IOException e) {
+ // Ignored, not much we can do anyway
+ }
+ }
+
+ return line;
+ }
+
+ /**
+ * Writes the given value into the given file
+ *
+ * @return true on success, false on failure
+ */
+ public static boolean writeLine(String fileName, String value) {
+ BufferedWriter writer = null;
+
+ try {
+ writer = new BufferedWriter(new FileWriter(fileName));
+ writer.write(value);
+ } catch (FileNotFoundException e) {
+ Log.w(TAG, "No such file " + fileName + " for writing", e);
+ return false;
+ } catch (IOException e) {
+ Log.e(TAG, "Could not write to file " + fileName, e);
+ return false;
+ } finally {
+ try {
+ if (writer != null) {
+ writer.close();
+ }
+ } catch (IOException e) {
+ // Ignored, not much we can do anyway
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Checks whether the given file exists
+ *
+ * @return true if exists, false if not
+ */
+ public static boolean fileExists(String fileName) {
+ final File file = new File(fileName);
+ return file.exists();
+ }
+
+ /**
+ * Checks whether the given file is readable
+ *
+ * @return true if readable, false if not
+ */
+ public static boolean isFileReadable(String fileName) {
+ final File file = new File(fileName);
+ return file.exists() && file.canRead();
+ }
+
+ /**
+ * Checks whether the given file is writable
+ *
+ * @return true if writable, false if not
+ */
+ public static boolean isFileWritable(String fileName) {
+ final File file = new File(fileName);
+ return file.exists() && file.canWrite();
+ }
+
+ /**
+ * Deletes an existing file
+ *
+ * @return true if the delete was successful, false if not
+ */
+ public static boolean delete(String fileName) {
+ final File file = new File(fileName);
+ boolean ok = false;
+ try {
+ ok = file.delete();
+ } catch (SecurityException e) {
+ Log.w(TAG, "SecurityException trying to delete " + fileName, e);
+ }
+ return ok;
+ }
+
+ /**
+ * Renames an existing file
+ *
+ * @return true if the rename was successful, false if not
+ */
+ public static boolean rename(String srcPath, String dstPath) {
+ final File srcFile = new File(srcPath);
+ final File dstFile = new File(dstPath);
+ boolean ok = false;
+ try {
+ ok = srcFile.renameTo(dstFile);
+ } catch (SecurityException e) {
+ Log.w(TAG, "SecurityException trying to rename " + srcPath + " to " + dstPath, e);
+ } catch (NullPointerException e) {
+ Log.e(TAG, "NullPointerException trying to rename " + srcPath + " to " + dstPath, e);
+ }
+ return ok;
+ }
+}
diff --git a/src/org/lineageos/internal/util/ImageUtils.java b/src/org/lineageos/internal/util/ImageUtils.java
new file mode 100644
index 0000000..5b5567a
--- /dev/null
+++ b/src/org/lineageos/internal/util/ImageUtils.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2013-2014 The CyanogenMod Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.lineageos.internal.util;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Point;
+import android.util.Log;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+
+public class ImageUtils {
+ private static final String TAG = ImageUtils.class.getSimpleName();
+
+ private static final String ASSET_URI_PREFIX = "file:///android_asset/";
+ private static final int DEFAULT_IMG_QUALITY = 100;
+
+ /**
+ * Gets the Width and Height of the image
+ *
+ * @param inputStream The input stream of the image
+ *
+ * @return A point structure that holds the Width and Height (x and y)/*"
+ */
+ public static Point getImageDimension(InputStream inputStream) {
+ if (inputStream == null) {
+ throw new IllegalArgumentException("'inputStream' cannot be null!");
+ }
+ BitmapFactory.Options options = new BitmapFactory.Options();
+ options.inJustDecodeBounds = true;
+ BitmapFactory.decodeStream(inputStream, null, options);
+ Point point = new Point(options.outWidth,options.outHeight);
+ return point;
+ }
+
+ /**
+ * Crops the input image and returns a new InputStream of the cropped area
+ *
+ * @param inputStream The input stream of the image
+ * @param imageWidth Width of the input image
+ * @param imageHeight Height of the input image
+ * @param inputStream Desired Width
+ * @param inputStream Desired Width
+ *
+ * @return a new InputStream of the cropped area/*"
+ */
+ public static InputStream cropImage(InputStream inputStream, int imageWidth, int imageHeight,
+ int outWidth, int outHeight) throws IllegalArgumentException {
+ if (inputStream == null){
+ throw new IllegalArgumentException("inputStream cannot be null");
+ }
+
+ if (imageWidth <= 0 || imageHeight <= 0) {
+ throw new IllegalArgumentException(
+ String.format("imageWidth and imageHeight must be > 0: imageWidth=%d" +
+ " imageHeight=%d", imageWidth, imageHeight));
+ }
+
+ if (outWidth <= 0 || outHeight <= 0) {
+ throw new IllegalArgumentException(
+ String.format("outWidth and outHeight must be > 0: outWidth=%d" +
+ " outHeight=%d", imageWidth, outHeight));
+ }
+
+ int scaleDownSampleSize = Math.min(imageWidth / outWidth, imageHeight / outHeight);
+ if (scaleDownSampleSize > 0) {
+ imageWidth /= scaleDownSampleSize;
+ imageHeight /= scaleDownSampleSize;
+ } else {
+ float ratio = (float) outWidth / outHeight;
+ if (imageWidth < imageHeight * ratio) {
+ outWidth = imageWidth;
+ outHeight = (int) (outWidth / ratio);
+ } else {
+ outHeight = imageHeight;
+ outWidth = (int) (outHeight * ratio);
+ }
+ }
+ int left = (imageWidth - outWidth) / 2;
+ int top = (imageHeight - outHeight) / 2;
+ InputStream compressed = null;
+ try {
+ BitmapFactory.Options options = new BitmapFactory.Options();
+ if (scaleDownSampleSize > 1) {
+ options.inSampleSize = scaleDownSampleSize;
+ }
+ Bitmap bitmap = BitmapFactory.decodeStream(inputStream, null, options);
+ if (bitmap == null) {
+ return null;
+ }
+ Bitmap cropped = Bitmap.createBitmap(bitmap, left, top, outWidth, outHeight);
+ ByteArrayOutputStream tmpOut = new ByteArrayOutputStream(2048);
+ if (cropped.compress(Bitmap.CompressFormat.PNG, DEFAULT_IMG_QUALITY, tmpOut)) {
+ byte[] outByteArray = tmpOut.toByteArray();
+ compressed = new ByteArrayInputStream(outByteArray);
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Exception " + e);
+ }
+ return compressed;
+ }
+}
diff --git a/src/org/lineageos/internal/util/MathUtils.java b/src/org/lineageos/internal/util/MathUtils.java
new file mode 100644
index 0000000..d4a2639
--- /dev/null
+++ b/src/org/lineageos/internal/util/MathUtils.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2016 The CyanogenMod Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.lineageos.internal.util;
+
+public final class MathUtils {
+
+ /**
+ * Given a range of values which change continuously in a non-linear way,
+ * we can map back and forth to a linear scale using some quadratic equations.
+ *
+ * The linear scale ranges from 0 -> 1. This method will calculate the
+ * coefficients needed to solve the conversion functions in the next two methods.
+ *
+ * lower = actual value when linear value = 0
+ * mid = actual value when linear value = .5
+ * upper actual value when linear value = 1
+ *
+ * @param lower
+ * @param mid
+ * @param upper
+ * @return array of coefficients
+ */
+ public static double[] powerCurve(double lower, double mid, double upper) {
+ final double[] curve = new double[3];
+ curve[0] = ((lower * upper) - (mid * mid)) / (lower - (2 * mid) + upper);
+ curve[1] = Math.pow((mid - lower), 2) / (lower - (2 * mid) + upper);
+ curve[2] = 2 * Math.log((upper - mid) / (mid - lower));
+ return curve;
+ }
+
+ /**
+ * Map a value on a power curve to a linear value
+ *
+ * @param curve obtained from powerCurve()
+ * @param value to convert to linear scale
+ * @return linear value from 0 -> 1
+ */
+ public static double powerCurveToLinear(final double[] curve, double value) {
+ return Math.log((value - curve[0]) / curve[1]) / curve[2];
+ }
+
+ /**
+ * Map a value on a linear scale to a value on a power curve
+ *
+ * @param curve obtained from powerCurve()
+ * @param value from 0 -> 1 to map onto power curve
+ * @return actual value on the given curve
+ */
+ public static double linearToPowerCurve(final double[] curve, double value) {
+ return curve[0] + curve[1] * Math.exp(curve[2] * value);
+ }
+
+
+}
diff --git a/src/org/lineageos/internal/util/PackageManagerUtils.java b/src/org/lineageos/internal/util/PackageManagerUtils.java
new file mode 100644
index 0000000..075dd5c
--- /dev/null
+++ b/src/org/lineageos/internal/util/PackageManagerUtils.java
@@ -0,0 +1,117 @@
+/**
+ * Copyright (C) 2016 The CyanogenMod Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.lineageos.internal.util;
+
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+
+public final class PackageManagerUtils {
+ private static final int FLAG_SUSPENDED = 1 << 30;
+
+ private PackageManagerUtils() {
+ // This class is not supposed to be instantiated
+ }
+
+ /**
+ * Checks whether a given package exists
+ *
+ * @param context
+ * @param packageName
+ * @return true if the package exists
+ */
+ public static boolean isAppInstalled(final Context context, final String packageName) {
+ return getApplicationInfo(context, packageName, 0) != null;
+ }
+
+ /**
+ * Check whether a package with specific flags is enabled
+ *
+ * @param context
+ * @param packageName
+ * @param flags
+ * @return true if the package is enabled
+ */
+ public static boolean isAppEnabled(final Context context,
+ final String packageName, final int flags) {
+ final ApplicationInfo info = getApplicationInfo(context, packageName, flags);
+ return info != null && info.enabled;
+ }
+
+ /**
+ * Check whether a package is enabled
+ *
+ * @param context
+ * @param packageName
+ * @return true if the package is enabled
+ */
+ public static boolean isAppEnabled(final Context context, final String packageName) {
+ return isAppEnabled(context, packageName, 0);
+ }
+
+ /**
+ * Check if a package can possibly be on the SDCard
+ * This is just a workaround and doesn't guarantee that the app is on SD card
+ *
+ * @param context
+ * @param packageName
+ * @return true if the package is on the SDCard
+ */
+ public static boolean isAppOnSdcard(final Context context, final String packageName) {
+ return isAppEnabled(context, packageName, PackageManager.GET_UNINSTALLED_PACKAGES);
+ }
+
+ /**
+ * Check if a package is suspended
+ *
+ * @param context
+ * @param packageName
+ * @return true if the package is suspended
+ */
+ public static boolean isAppSuspended(final Context context, final String packageName) {
+ return isAppSuspended(getApplicationInfo(context, packageName, 0));
+ }
+
+ /**
+ * Check if a package is suspended
+ *
+ * @param info
+ * @return true if the package is suspended
+ */
+ public static boolean isAppSuspended(final ApplicationInfo info) {
+ return info != null && (info.flags & FLAG_SUSPENDED) != 0;
+ }
+
+ /**
+ * Get the ApplicationInfo of a package
+ *
+ * @param context
+ * @param packageName
+ * @param flags
+ * @return null if the package cannot be found or the ApplicationInfo is null
+ */
+ public static ApplicationInfo getApplicationInfo(final Context context,
+ final String packageName, final int flags) {
+ final PackageManager packageManager = context.getPackageManager();
+ ApplicationInfo info;
+ try {
+ info = packageManager.getApplicationInfo(packageName, flags);
+ } catch (PackageManager.NameNotFoundException e) {
+ info = null;
+ }
+ return info;
+ }
+}
diff --git a/src/org/lineageos/internal/util/PowerMenuConstants.java b/src/org/lineageos/internal/util/PowerMenuConstants.java
new file mode 100644
index 0000000..b04deb2
--- /dev/null
+++ b/src/org/lineageos/internal/util/PowerMenuConstants.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2015 The CyanogenMod Project
+ * Copyright (C) 2017-2022 The LineageOS Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.lineageos.internal.util;
+
+/* Master list of all actions for the power menu */
+public class PowerMenuConstants {
+ public static final String GLOBAL_ACTION_KEY_POWER = "power";
+ public static final String GLOBAL_ACTION_KEY_RESTART = "restart";
+ public static final String GLOBAL_ACTION_KEY_SCREENSHOT = "screenshot";
+ public static final String GLOBAL_ACTION_KEY_AIRPLANE = "airplane";
+ public static final String GLOBAL_ACTION_KEY_USERS = "users";
+ public static final String GLOBAL_ACTION_KEY_SETTINGS = "settings";
+ public static final String GLOBAL_ACTION_KEY_LOCKDOWN = "lockdown";
+ public static final String GLOBAL_ACTION_KEY_BUGREPORT = "bugreport";
+ public static final String GLOBAL_ACTION_KEY_SILENT = "silent";
+ public static final String GLOBAL_ACTION_KEY_VOICEASSIST = "voiceassist";
+ public static final String GLOBAL_ACTION_KEY_ASSIST = "assist";
+ public static final String GLOBAL_ACTION_KEY_LOGOUT = "logout";
+ public static final String GLOBAL_ACTION_KEY_EMERGENCY = "emergency";
+ public static final String GLOBAL_ACTION_KEY_DEVICECONTROLS = "devicecontrols";
+
+ /**
+ * Advanced restart menu actions
+ */
+ public static final String GLOBAL_ACTION_KEY_RESTART_RECOVERY = "restart_recovery";
+ public static final String GLOBAL_ACTION_KEY_RESTART_BOOTLOADER = "restart_bootloader";
+ public static final String GLOBAL_ACTION_KEY_RESTART_DOWNLOAD = "restart_download";
+ public static final String GLOBAL_ACTION_KEY_RESTART_FASTBOOT = "restart_fastboot";
+
+ private static String[] ALL_ACTIONS = {
+ GLOBAL_ACTION_KEY_EMERGENCY,
+ GLOBAL_ACTION_KEY_LOCKDOWN,
+ GLOBAL_ACTION_KEY_POWER,
+ GLOBAL_ACTION_KEY_RESTART,
+ GLOBAL_ACTION_KEY_SCREENSHOT,
+ GLOBAL_ACTION_KEY_AIRPLANE,
+ GLOBAL_ACTION_KEY_USERS,
+ GLOBAL_ACTION_KEY_SETTINGS,
+ GLOBAL_ACTION_KEY_BUGREPORT,
+ GLOBAL_ACTION_KEY_SILENT,
+ GLOBAL_ACTION_KEY_VOICEASSIST,
+ GLOBAL_ACTION_KEY_ASSIST,
+ GLOBAL_ACTION_KEY_DEVICECONTROLS,
+ GLOBAL_ACTION_KEY_LOGOUT,
+ };
+
+ public static String[] getAllActions() {
+ return ALL_ACTIONS;
+ }
+}
diff --git a/src/org/lineageos/internal/util/ScreenType.java b/src/org/lineageos/internal/util/ScreenType.java
new file mode 100644
index 0000000..d1729f1
--- /dev/null
+++ b/src/org/lineageos/internal/util/ScreenType.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2015 The CyanogenMod Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.lineageos.internal.util;
+
+import android.content.Context;
+import android.util.DisplayMetrics;
+import android.view.DisplayInfo;
+import android.view.WindowManager;
+
+public class ScreenType {
+ // Device type reference
+ private static int sDeviceType = -1;
+
+ // Device types
+ private static final int DEVICE_PHONE = 0;
+ private static final int DEVICE_HYBRID = 1;
+ private static final int DEVICE_TABLET = 2;
+
+ private static int getScreenType(Context context) {
+ if (sDeviceType == -1) {
+ WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+ DisplayInfo outDisplayInfo = new DisplayInfo();
+ wm.getDefaultDisplay().getDisplayInfo(outDisplayInfo);
+ int shortSize = Math.min(outDisplayInfo.logicalHeight, outDisplayInfo.logicalWidth);
+ int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT
+ / outDisplayInfo.logicalDensityDpi;
+ if (shortSizeDp < 600) {
+ // 0-599dp: "phone" UI with a separate status & navigation bar
+ sDeviceType = DEVICE_PHONE;
+ } else if (shortSizeDp < 720) {
+ // 600-719dp: "phone" UI with modifications for larger screens
+ sDeviceType = DEVICE_HYBRID;
+ } else {
+ // 720dp: "tablet" UI with a single combined status & navigation bar
+ sDeviceType = DEVICE_TABLET;
+ }
+ }
+ return sDeviceType;
+ }
+
+ public static boolean isPhone(Context context) {
+ return getScreenType(context) == DEVICE_PHONE;
+ }
+
+ public static boolean isHybrid(Context context) {
+ return getScreenType(context) == DEVICE_HYBRID;
+ }
+
+ public static boolean isTablet(Context context) {
+ return getScreenType(context) == DEVICE_TABLET;
+ }
+}