From acce2401740f38cd4130dcfe17f26b88e7495e9d Mon Sep 17 00:00:00 2001 From: DrDisagree Date: Thu, 21 Sep 2023 01:46:28 +0600 Subject: [PATCH] Add lockscreen Depth Wallpaper feature (Closes #230, closes #274) --- app/src/main/AndroidManifest.xml | 20 +- .../iconify/common/Preferences.java | 4 +- .../drdisagree/iconify/common/Resources.java | 2 + .../ui/activities/XposedDepthWallpaper.java | 125 ++++++++++ .../ui/activities/XposedLockscreenClock.java | 9 - .../iconify/ui/fragments/XposedMenu.java | 2 + .../ui/views/LockscreenClockStyles.java | 2 +- .../drdisagree/iconify/xposed/EntryList.java | 2 + .../iconify/xposed/mods/DepthWallpaper.java | 132 +++++++++++ .../iconify/xposed/mods/LockscreenClock.java | 218 +++++++++++------- .../xposed/utils/LockscreenClockStyles.java | 93 +++++--- .../ic_xposed_depth_wallpaper.xml | 15 ++ .../activity_xposed_depth_wallpaper.xml | 143 ++++++++++++ .../activity_xposed_lockscreen_clock.xml | 43 ---- app/src/main/res/values/strings.xml | 12 + 15 files changed, 641 insertions(+), 181 deletions(-) create mode 100644 app/src/main/java/com/drdisagree/iconify/ui/activities/XposedDepthWallpaper.java create mode 100644 app/src/main/java/com/drdisagree/iconify/xposed/mods/DepthWallpaper.java create mode 100644 app/src/main/res/drawable-v24/ic_xposed_depth_wallpaper.xml create mode 100644 app/src/main/res/layout/activity_xposed_depth_wallpaper.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7ecd32cb4..3900936a0 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -39,6 +39,9 @@ android:supportsRtl="true" android:theme="@style/Theme.Iconify" tools:targetApi="tiramisu"> + @@ -179,13 +182,14 @@ - + + @@ -193,13 +197,13 @@ - + diff --git a/app/src/main/java/com/drdisagree/iconify/common/Preferences.java b/app/src/main/java/com/drdisagree/iconify/common/Preferences.java index 1a3aed0e7..d88e3af8a 100644 --- a/app/src/main/java/com/drdisagree/iconify/common/Preferences.java +++ b/app/src/main/java/com/drdisagree/iconify/common/Preferences.java @@ -34,7 +34,6 @@ public class Preferences { public static final String HEADER_CLOCK_FONT_TEXT_SCALING = "xposed_headerclocktextscaling"; public static final String QSPANEL_HIDE_CARRIER = "xposed_qspanelhidecarrier"; public static final String LSCLOCK_SWITCH = "xposed_lockscreenclock"; - public static final String LSCLOCK_AUTOHIDE = "xposed_lockscreenclockautohide"; public static final String LSCLOCK_STYLE = "xposed_lockscreenclockstyle"; public static final String LSCLOCK_TOPMARGIN = "xposed_lockscreenclocktopmargin"; public static final String LSCLOCK_BOTTOMMARGIN = "xposed_lockscreenclockbottommargin"; @@ -60,7 +59,8 @@ public class Preferences { public static final String CUSTOM_BATTERY_HEIGHT = "xposed_custombatteryheight"; public static final String CUSTOM_BATTERY_MARGIN = "xposed_custombatterymargin"; public static final String HEADER_QQS_TOPMARGIN = "qqspanelTopMargin"; - public static final String HIDE_DATA_DISABLED_ICON = "hideDataDisabledIcon"; + public static final String HIDE_DATA_DISABLED_ICON = "xposed_hideDataDisabledIcon"; + public static final String DEPTH_WALLPAPER_SWITCH = "xposed_depthwallpaper"; // Battery styles public static final int BATTERY_STYLE_DEFAULT = 0; diff --git a/app/src/main/java/com/drdisagree/iconify/common/Resources.java b/app/src/main/java/com/drdisagree/iconify/common/Resources.java index 25444f471..70f814281 100644 --- a/app/src/main/java/com/drdisagree/iconify/common/Resources.java +++ b/app/src/main/java/com/drdisagree/iconify/common/Resources.java @@ -43,6 +43,8 @@ public class Resources { public static final String LSCLOCK_FONT_DIR = XPOSED_RESOURCE_TEMP_DIR + "/lsclock_font.ttf"; public static final String HEADER_CLOCK_FONT_DIR = XPOSED_RESOURCE_TEMP_DIR + "/headerclock_font.ttf"; public static final String HEADER_IMAGE_DIR = XPOSED_RESOURCE_TEMP_DIR + "/header_image.png"; + public static final String DEPTH_WALL_FG_DIR = XPOSED_RESOURCE_TEMP_DIR + "/depth_wallpaper_fg.png"; + public static final String DEPTH_WALL_BG_DIR = XPOSED_RESOURCE_TEMP_DIR + "/depth_wallpaper_bg.png"; // Overlays public static final String QSC_overlay = "IconifyComponentQSC.overlay"; diff --git a/app/src/main/java/com/drdisagree/iconify/ui/activities/XposedDepthWallpaper.java b/app/src/main/java/com/drdisagree/iconify/ui/activities/XposedDepthWallpaper.java new file mode 100644 index 000000000..5603f53dd --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/activities/XposedDepthWallpaper.java @@ -0,0 +1,125 @@ +package com.drdisagree.iconify.ui.activities; + +import static com.drdisagree.iconify.common.Const.SWITCH_ANIMATION_DELAY; +import static com.drdisagree.iconify.common.Preferences.DEPTH_WALLPAPER_SWITCH; +import static com.drdisagree.iconify.common.Resources.DEPTH_WALL_BG_DIR; +import static com.drdisagree.iconify.common.Resources.DEPTH_WALL_FG_DIR; +import static com.drdisagree.iconify.utils.FileUtil.copyToIconifyHiddenDir; +import static com.drdisagree.iconify.utils.FileUtil.getRealPath; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.widget.Toast; + +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; +import androidx.appcompat.app.AppCompatActivity; + +import com.drdisagree.iconify.R; +import com.drdisagree.iconify.config.RPrefs; +import com.drdisagree.iconify.databinding.ActivityXposedDepthWallpaperBinding; +import com.drdisagree.iconify.ui.utils.ViewHelper; +import com.drdisagree.iconify.utils.SystemUtil; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; + +public class XposedDepthWallpaper extends AppCompatActivity { + + private ActivityXposedDepthWallpaperBinding binding; + ActivityResultLauncher intentForegroundImage = registerForActivityResult( + new ActivityResultContracts.StartActivityForResult(), + result -> { + if (result.getResultCode() == Activity.RESULT_OK) { + Intent data = result.getData(); + String path = getRealPath(data); + + if (path != null && copyToIconifyHiddenDir(path, DEPTH_WALL_FG_DIR)) { + RPrefs.putBoolean(DEPTH_WALLPAPER_SWITCH, !binding.enableDepthWallpaper.isChecked()); + RPrefs.putBoolean(DEPTH_WALLPAPER_SWITCH, binding.enableDepthWallpaper.isChecked()); + Toast.makeText(getApplicationContext(), getString(R.string.toast_selected_successfully), Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(getApplicationContext(), getResources().getString(R.string.toast_rename_file), Toast.LENGTH_SHORT).show(); + } + } + }); + ActivityResultLauncher intentBackgroundImage = registerForActivityResult( + new ActivityResultContracts.StartActivityForResult(), + result -> { + if (result.getResultCode() == Activity.RESULT_OK) { + Intent data = result.getData(); + String path = getRealPath(data); + + if (path != null && copyToIconifyHiddenDir(path, DEPTH_WALL_BG_DIR)) { + RPrefs.putBoolean(DEPTH_WALLPAPER_SWITCH, !binding.enableDepthWallpaper.isChecked()); + RPrefs.putBoolean(DEPTH_WALLPAPER_SWITCH, binding.enableDepthWallpaper.isChecked()); + Toast.makeText(getApplicationContext(), getString(R.string.toast_selected_successfully), Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(getApplicationContext(), getResources().getString(R.string.toast_rename_file), Toast.LENGTH_SHORT).show(); + } + } + }); + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + binding = ActivityXposedDepthWallpaperBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + + // Header + ViewHelper.setHeader(this, binding.header.toolbar, R.string.activity_title_depth_wallpaper); + + // Alert dialog + new MaterialAlertDialogBuilder(this, R.style.MaterialComponents_MaterialAlertDialog) + .setTitle(getString(R.string.attention)) + .setMessage(getString(R.string.depth_wallpaper_alert_msg)) + .setPositiveButton(getString(R.string.understood), (dialog, which) -> dialog.dismiss()) + .setCancelable(true) + .show(); + + // Enable depth wallpaper + binding.enableDepthWallpaper.setChecked(RPrefs.getBoolean(DEPTH_WALLPAPER_SWITCH, false)); + binding.enableDepthWallpaper.setOnCheckedChangeListener((buttonView, isChecked) -> { + RPrefs.putBoolean(DEPTH_WALLPAPER_SWITCH, isChecked); + binding.pickForegroundImg.setEnabled(isChecked); + binding.pickBackgroundImg.setEnabled(isChecked); + new Handler(Looper.getMainLooper()).postDelayed(SystemUtil::handleSystemUIRestart, SWITCH_ANIMATION_DELAY); + }); + binding.enableDepthWallpaperContainer.setOnClickListener(v -> binding.enableDepthWallpaper.toggle()); + + // Foreground image + binding.pickForegroundImg.setEnabled(binding.enableDepthWallpaper.isChecked()); + binding.pickForegroundImg.setOnClickListener(v -> { + if (!SystemUtil.hasStoragePermission()) { + SystemUtil.requestStoragePermission(this); + } else { + browseForegroundImage(); + } + }); + + // Background image + binding.pickBackgroundImg.setEnabled(binding.enableDepthWallpaper.isChecked()); + binding.pickBackgroundImg.setOnClickListener(v -> { + if (!SystemUtil.hasStoragePermission()) { + SystemUtil.requestStoragePermission(this); + } else { + browseBackgroundImage(); + } + }); + } + + public void browseForegroundImage() { + Intent chooseFile = new Intent(Intent.ACTION_GET_CONTENT); + chooseFile.addCategory(Intent.CATEGORY_OPENABLE); + chooseFile.setType("image/*"); + intentForegroundImage.launch(chooseFile); + } + + public void browseBackgroundImage() { + Intent chooseFile = new Intent(Intent.ACTION_GET_CONTENT); + chooseFile.addCategory(Intent.CATEGORY_OPENABLE); + chooseFile.setType("image/*"); + intentBackgroundImage.launch(chooseFile); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/activities/XposedLockscreenClock.java b/app/src/main/java/com/drdisagree/iconify/ui/activities/XposedLockscreenClock.java index fa8d5920a..4e28f0b63 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/activities/XposedLockscreenClock.java +++ b/app/src/main/java/com/drdisagree/iconify/ui/activities/XposedLockscreenClock.java @@ -1,7 +1,6 @@ package com.drdisagree.iconify.ui.activities; import static com.drdisagree.iconify.common.Const.SWITCH_ANIMATION_DELAY; -import static com.drdisagree.iconify.common.Preferences.LSCLOCK_AUTOHIDE; import static com.drdisagree.iconify.common.Preferences.LSCLOCK_BOTTOMMARGIN; import static com.drdisagree.iconify.common.Preferences.LSCLOCK_COLOR_CODE; import static com.drdisagree.iconify.common.Preferences.LSCLOCK_COLOR_SWITCH; @@ -86,14 +85,6 @@ protected void onCreate(Bundle savedInstanceState) { }); binding.enableLockscreenClockContainer.setOnClickListener(v -> binding.enableLockscreenClock.toggle()); - // Auto hide clock - binding.enableAutoHideClock.setChecked(RPrefs.getBoolean(LSCLOCK_AUTOHIDE, false)); - binding.enableAutoHideClock.setOnCheckedChangeListener((buttonView, isChecked) -> { - RPrefs.putBoolean(LSCLOCK_AUTOHIDE, isChecked); - new Handler(Looper.getMainLooper()).postDelayed(SystemUtil::handleSystemUIRestart, SWITCH_ANIMATION_DELAY); - }); - binding.autoHideClockContainer.setOnClickListener(v -> binding.enableAutoHideClock.toggle()); - // Lockscreen clock style binding.lockscreenClockPreview.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL); ClockPreviewAdapter adapter = initLockscreenClockStyles(); diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/XposedMenu.java b/app/src/main/java/com/drdisagree/iconify/ui/fragments/XposedMenu.java index c1685a5b4..16aacafff 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/XposedMenu.java +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/XposedMenu.java @@ -44,6 +44,7 @@ import com.drdisagree.iconify.databinding.FragmentXposedMenuBinding; import com.drdisagree.iconify.ui.activities.XposedBackgroundChip; import com.drdisagree.iconify.ui.activities.XposedBatteryStyle; +import com.drdisagree.iconify.ui.activities.XposedDepthWallpaper; import com.drdisagree.iconify.ui.activities.XposedHeaderClock; import com.drdisagree.iconify.ui.activities.XposedHeaderImage; import com.drdisagree.iconify.ui.activities.XposedLockscreenClock; @@ -200,6 +201,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, xposed_menu.add(new Object[]{XposedHeaderImage.class, getResources().getString(R.string.activity_title_header_image), getResources().getString(R.string.activity_desc_header_image), R.drawable.ic_xposed_header_image}); xposed_menu.add(new Object[]{XposedHeaderClock.class, getResources().getString(R.string.activity_title_header_clock), getResources().getString(R.string.activity_desc_header_clock), R.drawable.ic_xposed_header_clock}); xposed_menu.add(new Object[]{XposedLockscreenClock.class, getResources().getString(R.string.activity_title_lockscreen_clock), getResources().getString(R.string.activity_desc_lockscreen_clock), R.drawable.ic_xposed_lockscreen}); + xposed_menu.add(new Object[]{XposedDepthWallpaper.class, getResources().getString(R.string.activity_title_depth_wallpaper), getResources().getString(R.string.activity_desc_depth_wallpaper), R.drawable.ic_xposed_depth_wallpaper}); xposed_menu.add(new Object[]{XposedBackgroundChip.class, getResources().getString(R.string.activity_title_background_chip), getResources().getString(R.string.activity_desc_background_chip), R.drawable.ic_xposed_background_chip}); xposed_menu.add(new Object[]{XposedOthers.class, getResources().getString(R.string.activity_title_xposed_others), getResources().getString(R.string.activity_desc_xposed_others), R.drawable.ic_xposed_misc}); diff --git a/app/src/main/java/com/drdisagree/iconify/ui/views/LockscreenClockStyles.java b/app/src/main/java/com/drdisagree/iconify/ui/views/LockscreenClockStyles.java index cfad1dbc0..29aceaf0a 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/views/LockscreenClockStyles.java +++ b/app/src/main/java/com/drdisagree/iconify/ui/views/LockscreenClockStyles.java @@ -540,7 +540,7 @@ public static LinearLayout initLockscreenClockStyle(Context mContext, int style) final TextClock date8 = new TextClock(mContext); ViewGroup.MarginLayoutParams dateParams8 = new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.WRAP_CONTENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT); - dateParams8.setMargins(0, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 6 + lineHeight, mContext.getResources().getDisplayMetrics()), 0, 0); + dateParams8.setMargins(0, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, lineHeight, mContext.getResources().getDisplayMetrics()), 0, 0); date8.setLayoutParams(dateParams8); date8.setFormat12Hour("MMMM dd"); date8.setFormat24Hour("MMMM dd"); diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/EntryList.java b/app/src/main/java/com/drdisagree/iconify/xposed/EntryList.java index 3da2bd4d9..5b9c0a4a5 100644 --- a/app/src/main/java/com/drdisagree/iconify/xposed/EntryList.java +++ b/app/src/main/java/com/drdisagree/iconify/xposed/EntryList.java @@ -24,6 +24,7 @@ import com.drdisagree.iconify.xposed.mods.BackgroundChip; import com.drdisagree.iconify.xposed.mods.BatteryStyleManager; +import com.drdisagree.iconify.xposed.mods.DepthWallpaper; import com.drdisagree.iconify.xposed.mods.HeaderClock; import com.drdisagree.iconify.xposed.mods.HeaderImage; import com.drdisagree.iconify.xposed.mods.HookCheck; @@ -54,6 +55,7 @@ public static ArrayList> getEntries(String packageName) modPacks.add(BackgroundChip.class); modPacks.add(HeaderClock.class); modPacks.add(HeaderImage.class); + modPacks.add(DepthWallpaper.class); modPacks.add(LockscreenClock.class); modPacks.add(Miscellaneous.class); modPacks.add(QSBlackTheme.class); diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/mods/DepthWallpaper.java b/app/src/main/java/com/drdisagree/iconify/xposed/mods/DepthWallpaper.java new file mode 100644 index 000000000..f671909ec --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/xposed/mods/DepthWallpaper.java @@ -0,0 +1,132 @@ +package com.drdisagree.iconify.xposed.mods; + +import static com.drdisagree.iconify.common.Const.SYSTEMUI_PACKAGE; +import static com.drdisagree.iconify.common.Preferences.DEPTH_WALLPAPER_SWITCH; +import static com.drdisagree.iconify.config.XPrefs.Xprefs; +import static de.robv.android.xposed.XposedBridge.hookAllMethods; +import static de.robv.android.xposed.XposedHelpers.findClass; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.graphics.ImageDecoder; +import android.graphics.drawable.Drawable; +import android.os.Environment; +import android.view.View; +import android.view.ViewGroup; +import android.widget.FrameLayout; +import android.widget.ImageView; + +import com.drdisagree.iconify.xposed.ModPack; + +import java.io.File; +import java.util.Objects; + +import de.robv.android.xposed.XC_MethodHook; +import de.robv.android.xposed.callbacks.XC_LoadPackage; + +@SuppressLint("DiscouragedApi") +public class DepthWallpaper extends ModPack { + + private static final String TAG = "Iconify - " + DepthWallpaper.class.getSimpleName() + ": "; + private boolean showDepthWallpaper = false; + private FrameLayout mDepthWallpaperLayout = null; + private ImageView mDepthWallpaperBackground = null; + private ImageView mDepthWallpaperForeground = null; + + public DepthWallpaper(Context context) { + super(context); + } + + @Override + public void updatePrefs(String... Key) { + if (Xprefs == null) return; + + showDepthWallpaper = Xprefs.getBoolean(DEPTH_WALLPAPER_SWITCH, false); + + if (Key.length > 0 && Objects.equals(Key[0], DEPTH_WALLPAPER_SWITCH)) { + updateWallpaper(); + } + } + + @Override + public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) { + Class KeyguardBottomAreaViewClass = findClass(SYSTEMUI_PACKAGE + ".statusbar.phone.KeyguardBottomAreaView", lpparam.classLoader); + + hookAllMethods(KeyguardBottomAreaViewClass, "onFinishInflate", new XC_MethodHook() { + @Override + protected void afterHookedMethod(MethodHookParam param) { + View view = (View) param.thisObject; + ViewGroup container = view.findViewById(mContext.getResources().getIdentifier("keyguard_indication_area", "id", mContext.getPackageName())); + + container.setClipChildren(false); + container.setClipToPadding(false); + container.getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT; + container.getLayoutParams().width = ViewGroup.LayoutParams.MATCH_PARENT; + ((ViewGroup.MarginLayoutParams) container.getLayoutParams()).bottomMargin = 0; + + // Get the depth wallpaper layout + String depth_wall_tag = "iconify_depth_wallpaper"; + mDepthWallpaperLayout = container.findViewWithTag(depth_wall_tag); + + // Create the depth wallpaper layout if it doesn't exist + if (mDepthWallpaperLayout == null) { + mDepthWallpaperLayout = new FrameLayout(mContext); + mDepthWallpaperLayout.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); + mDepthWallpaperLayout.setTag(depth_wall_tag); + + container.addView(mDepthWallpaperLayout, 0); + } + + mDepthWallpaperBackground = new ImageView(mContext); + mDepthWallpaperForeground = new ImageView(mContext); + + mDepthWallpaperBackground.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); + mDepthWallpaperForeground.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); + + mDepthWallpaperLayout.addView(mDepthWallpaperBackground, 0); + mDepthWallpaperLayout.addView(mDepthWallpaperForeground); + + updateWallpaper(); + } + }); + + hookAllMethods(KeyguardBottomAreaViewClass, "onConfigurationChanged", new XC_MethodHook() { + @Override + protected void afterHookedMethod(MethodHookParam param) { + updateWallpaper(); + } + }); + } + + private void updateWallpaper() { + if (mDepthWallpaperLayout == null) return; + + if (!showDepthWallpaper) { + mDepthWallpaperLayout.setVisibility(View.GONE); + return; + } + + try { + ImageDecoder.Source backgroundImg = ImageDecoder.createSource(new File(Environment.getExternalStorageDirectory() + "/.iconify_files/depth_wallpaper_bg.png")); + ImageDecoder.Source foregroundImg = ImageDecoder.createSource(new File(Environment.getExternalStorageDirectory() + "/.iconify_files/depth_wallpaper_fg.png")); + + Drawable backgroundDrawable = ImageDecoder.decodeDrawable(backgroundImg); + Drawable foregroundDrawable = ImageDecoder.decodeDrawable(foregroundImg); + + mDepthWallpaperBackground.setImageDrawable(backgroundDrawable); + mDepthWallpaperBackground.setClipToOutline(true); + mDepthWallpaperBackground.setScaleType(ImageView.ScaleType.CENTER_CROP); + mDepthWallpaperBackground.setScaleX(1.1f); + mDepthWallpaperBackground.setScaleY(1.1f); + + mDepthWallpaperForeground.setImageDrawable(foregroundDrawable); + mDepthWallpaperForeground.setClipToOutline(true); + mDepthWallpaperForeground.setScaleType(ImageView.ScaleType.CENTER_CROP); + mDepthWallpaperForeground.setScaleX(1.1f); + mDepthWallpaperForeground.setScaleY(1.1f); + + mDepthWallpaperLayout.setVisibility(View.VISIBLE); + } catch (Throwable ignored) { + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/mods/LockscreenClock.java b/app/src/main/java/com/drdisagree/iconify/xposed/mods/LockscreenClock.java index b645e8aaa..9cc148dea 100644 --- a/app/src/main/java/com/drdisagree/iconify/xposed/mods/LockscreenClock.java +++ b/app/src/main/java/com/drdisagree/iconify/xposed/mods/LockscreenClock.java @@ -1,7 +1,7 @@ package com.drdisagree.iconify.xposed.mods; import static com.drdisagree.iconify.common.Const.SYSTEMUI_PACKAGE; -import static com.drdisagree.iconify.common.Preferences.LSCLOCK_AUTOHIDE; +import static com.drdisagree.iconify.common.Preferences.DEPTH_WALLPAPER_SWITCH; import static com.drdisagree.iconify.common.Preferences.LSCLOCK_BOTTOMMARGIN; import static com.drdisagree.iconify.common.Preferences.LSCLOCK_COLOR_CODE; import static com.drdisagree.iconify.common.Preferences.LSCLOCK_COLOR_SWITCH; @@ -24,10 +24,12 @@ import android.content.IntentFilter; import android.os.Handler; import android.os.Looper; +import android.view.Gravity; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; import android.widget.GridLayout; +import android.widget.LinearLayout; import android.widget.RelativeLayout; import com.drdisagree.iconify.xposed.ModPack; @@ -42,10 +44,10 @@ public class LockscreenClock extends ModPack implements IXposedHookLoadPackage { private static final String TAG = "Iconify - " + LockscreenClock.class.getSimpleName() + ": "; - boolean showLockscreenClock = false; - boolean autoHideClock = false; + private boolean showLockscreenClock = false; + private boolean showDepthWallpaper = false; + private ViewGroup mClockViewContainer = null; private ViewGroup mStatusViewContainer = null; - private FrameLayout mLargeClockFrame = null; public LockscreenClock(Context context) { super(context); @@ -56,16 +58,20 @@ public void updatePrefs(String... Key) { if (Xprefs == null) return; showLockscreenClock = Xprefs.getBoolean(LSCLOCK_SWITCH, false); - autoHideClock = Xprefs.getBoolean(LSCLOCK_AUTOHIDE, false); - - if (Key.length > 0 && (Objects.equals(Key[0], LSCLOCK_SWITCH) || Objects.equals(Key[0], LSCLOCK_AUTOHIDE) || Objects.equals(Key[0], LSCLOCK_COLOR_SWITCH) || Objects.equals(Key[0], LSCLOCK_COLOR_CODE) || Objects.equals(Key[0], LSCLOCK_STYLE) || Objects.equals(Key[0], LSCLOCK_TOPMARGIN) || Objects.equals(Key[0], LSCLOCK_BOTTOMMARGIN) || Objects.equals(Key[0], LSCLOCK_FONT_LINEHEIGHT) || Objects.equals(Key[0], LSCLOCK_FONT_SWITCH) || Objects.equals(Key[0], LSCLOCK_TEXT_WHITE) || Objects.equals(Key[0], LSCLOCK_FONT_TEXT_SCALING))) { - if (!autoHideClock && mStatusViewContainer != null) { - updateClockView(mStatusViewContainer); - } - - if (autoHideClock && mLargeClockFrame != null) { - updateClockView(mLargeClockFrame); - } + showDepthWallpaper = Xprefs.getBoolean(DEPTH_WALLPAPER_SWITCH, false); + + if (Key.length > 0 && (Objects.equals(Key[0], LSCLOCK_SWITCH) || + Objects.equals(Key[0], DEPTH_WALLPAPER_SWITCH) || + Objects.equals(Key[0], LSCLOCK_COLOR_SWITCH) || + Objects.equals(Key[0], LSCLOCK_COLOR_CODE) || + Objects.equals(Key[0], LSCLOCK_STYLE) || + Objects.equals(Key[0], LSCLOCK_TOPMARGIN) || + Objects.equals(Key[0], LSCLOCK_BOTTOMMARGIN) || + Objects.equals(Key[0], LSCLOCK_FONT_LINEHEIGHT) || + Objects.equals(Key[0], LSCLOCK_FONT_SWITCH) || + Objects.equals(Key[0], LSCLOCK_TEXT_WHITE) || + Objects.equals(Key[0], LSCLOCK_FONT_TEXT_SCALING))) { + updateClockView(); } } @@ -75,64 +81,21 @@ public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) { if (!lpparam.packageName.equals(SYSTEMUI_PACKAGE)) return; Class KeyguardStatusViewClass = findClass("com.android.keyguard.KeyguardStatusView", lpparam.classLoader); - Class KeyguardClockSwitchClass = findClass("com.android.keyguard.KeyguardClockSwitch", lpparam.classLoader); - - hookAllMethods(KeyguardClockSwitchClass, "onFinishInflate", new XC_MethodHook() { - @Override - protected void afterHookedMethod(MethodHookParam param) { - if (!showLockscreenClock || !autoHideClock) return; - - mLargeClockFrame = (FrameLayout) getObjectField(param.thisObject, "mLargeClockFrame"); - - // Add broadcast receiver for updating clock - IntentFilter filter = new IntentFilter(); - filter.addAction(Intent.ACTION_TIME_TICK); - filter.addAction(Intent.ACTION_TIME_CHANGED); - filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); - filter.addAction(Intent.ACTION_LOCALE_CHANGED); - - BroadcastReceiver timeChangedReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (mLargeClockFrame != null && intent != null) { - new Handler(Looper.getMainLooper()).post(() -> { - mLargeClockFrame.removeAllViews(); - updateClockView(mLargeClockFrame); - }); - } - } - }; - mContext.registerReceiver(timeChangedReceiver, filter); - mLargeClockFrame.removeAllViews(); - updateClockView(mLargeClockFrame); - } - }); - - hookAllMethods(KeyguardClockSwitchClass, "updateClockViews", new XC_MethodHook() { + hookAllMethods(KeyguardStatusViewClass, "onFinishInflate", new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) { - if (!showLockscreenClock || !autoHideClock) return; + if (!showLockscreenClock) return; - View mStatusArea = (View) getObjectField(param.thisObject, "mStatusArea"); + mStatusViewContainer = (ViewGroup) getObjectField(param.thisObject, "mStatusViewContainer"); - if ((boolean) param.args[0]) { - mStatusArea.findViewById(mContext.getResources().getIdentifier("keyguard_slice_view", "id", mContext.getPackageName())).setVisibility(View.INVISIBLE); - } else { - mStatusArea.findViewById(mContext.getResources().getIdentifier("keyguard_slice_view", "id", mContext.getPackageName())).setVisibility(View.VISIBLE); + if (!showDepthWallpaper) { + mClockViewContainer = mStatusViewContainer; } - } - }); - hookAllMethods(KeyguardStatusViewClass, "onFinishInflate", new XC_MethodHook() { - @Override - protected void afterHookedMethod(MethodHookParam param) { - if (!showLockscreenClock || autoHideClock) return; - - mStatusViewContainer = (ViewGroup) getObjectField(param.thisObject, "mStatusViewContainer"); + // Hide stock clock GridLayout KeyguardStatusView = (GridLayout) param.thisObject; - // Hide stock clock RelativeLayout mClockView = KeyguardStatusView.findViewById(mContext.getResources().getIdentifier("keyguard_clock_container", "id", mContext.getPackageName())); mClockView.getLayoutParams().height = 0; mClockView.getLayoutParams().width = 0; @@ -143,38 +106,123 @@ protected void afterHookedMethod(MethodHookParam param) { mMediaHostContainer.getLayoutParams().width = 0; mMediaHostContainer.setVisibility(View.INVISIBLE); - // Add broadcast receiver for updating clock - IntentFilter filter = new IntentFilter(); - filter.addAction(Intent.ACTION_TIME_TICK); - filter.addAction(Intent.ACTION_TIME_CHANGED); - filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); - filter.addAction(Intent.ACTION_LOCALE_CHANGED); - - BroadcastReceiver timeChangedReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (mStatusViewContainer != null && intent != null) { - new Handler(Looper.getMainLooper()).post(() -> updateClockView(mStatusViewContainer)); - } - } - }; + registerClockUpdater(); + } + }); + + Class KeyguardBottomAreaViewClass = findClass(SYSTEMUI_PACKAGE + ".statusbar.phone.KeyguardBottomAreaView", lpparam.classLoader); + + hookAllMethods(KeyguardBottomAreaViewClass, "onFinishInflate", new XC_MethodHook() { + @Override + protected void afterHookedMethod(MethodHookParam param) { + if (!showLockscreenClock || !showDepthWallpaper) return; + + View view = (View) param.thisObject; + ViewGroup container = view.findViewById(mContext.getResources().getIdentifier("keyguard_indication_area", "id", mContext.getPackageName())); - mContext.registerReceiver(timeChangedReceiver, filter); - updateClockView(mStatusViewContainer); + container.setClipChildren(false); + container.setClipToPadding(false); + container.getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT; + container.getLayoutParams().width = ViewGroup.LayoutParams.MATCH_PARENT; + ((ViewGroup.MarginLayoutParams) container.getLayoutParams()).bottomMargin = 0; + + // Get the depth wallpaper layout + String depth_wall_tag = "iconify_depth_wallpaper"; + mClockViewContainer = container.findViewWithTag(depth_wall_tag); + + // Create the depth wallpaper layout if it doesn't exist + if (mClockViewContainer == null) { + mClockViewContainer = new FrameLayout(mContext); + mClockViewContainer.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); + mClockViewContainer.setTag(depth_wall_tag); + + container.addView(mClockViewContainer, 0); + } + + registerClockUpdater(); } }); } - private void updateClockView(ViewGroup viewGroup) { + // Broadcast receiver for updating clock + private void registerClockUpdater() { + if (mClockViewContainer == null) return; + + IntentFilter filter = new IntentFilter(); + filter.addAction(Intent.ACTION_TIME_TICK); + filter.addAction(Intent.ACTION_TIME_CHANGED); + filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); + filter.addAction(Intent.ACTION_LOCALE_CHANGED); + + BroadcastReceiver timeChangedReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (intent != null) { + new Handler(Looper.getMainLooper()).post(() -> updateClockView()); + } + } + }; + + mContext.registerReceiver(timeChangedReceiver, filter); + + updateClockView(); + } + + private void updateClockView() { + if (mClockViewContainer == null) return; + ViewGroup clockView = LockscreenClockStyles.getClock(mContext); String clock_tag = "iconify_lockscreen_clock"; - if (viewGroup.findViewWithTag(clock_tag) != null) { - viewGroup.removeView(viewGroup.findViewWithTag(clock_tag)); + + // Remove existing clock view + if (mClockViewContainer.findViewWithTag(clock_tag) != null) { + mClockViewContainer.removeView(mClockViewContainer.findViewWithTag(clock_tag)); } + if (clockView != null) { clockView.setTag(clock_tag); - viewGroup.addView(clockView, 0); - viewGroup.requestLayout(); + + int idx = 0; + String depth_wall_tag = "iconify_depth_wallpaper"; + + if (mClockViewContainer.getTag() == depth_wall_tag) { + /* + If the clock view container is the depth wallpaper container, we need to + add the clock view to the middle of foreground and background images + */ + if (mClockViewContainer.getChildCount() == 2) { + idx = 1; + } + + // Add a dummy layout to the status view container so that we can move notifications + if (mStatusViewContainer != null) { + String dummy_tag = "dummy_layout"; + LinearLayout dummyLayout = mStatusViewContainer.findViewWithTag(dummy_tag); + + if (dummyLayout == null) { + dummyLayout = new LinearLayout(mContext); + dummyLayout.setTag(dummy_tag); + + mStatusViewContainer.addView(dummyLayout, 0); + } + + dummyLayout.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 300)); + ViewGroup.MarginLayoutParams clockParams = (ViewGroup.MarginLayoutParams) clockView.getLayoutParams(); + ((LinearLayout.LayoutParams) clockView.getLayoutParams()).gravity = Gravity.CENTER_VERTICAL; + ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) dummyLayout.getLayoutParams(); + params.topMargin = clockParams.topMargin; + params.bottomMargin = clockParams.bottomMargin; + dummyLayout.setLayoutParams(params); + + mStatusViewContainer.requestLayout(); + } + } + + if (clockView.getParent() != null) { + ((ViewGroup) clockView.getParent()).removeView(clockView); + } + mClockViewContainer.addView(clockView, idx); + mClockViewContainer.requestLayout(); } } } \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/utils/LockscreenClockStyles.java b/app/src/main/java/com/drdisagree/iconify/xposed/utils/LockscreenClockStyles.java index af8e92f22..6ac851c73 100644 --- a/app/src/main/java/com/drdisagree/iconify/xposed/utils/LockscreenClockStyles.java +++ b/app/src/main/java/com/drdisagree/iconify/xposed/utils/LockscreenClockStyles.java @@ -331,19 +331,29 @@ public static ViewGroup getClock(Context mContext) { right5.addView(date5); right5.addView(month5); - final LinearLayout container5 = new LinearLayout(mContext); - LinearLayout.LayoutParams layoutParams5 = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); - layoutParams5.gravity = Gravity.CENTER_HORIZONTAL; - setMargins(layoutParams5, mContext, 24, topMargin, 24, bottomMargin); - container5.setLayoutParams(layoutParams5); - container5.setOrientation(LinearLayout.HORIZONTAL); - setPaddings(container5, mContext, 12, 12, 12, 12); + final LinearLayout tempContainer5 = new LinearLayout(mContext); + LinearLayout.LayoutParams tempLayoutParams5 = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); + tempLayoutParams5.gravity = Gravity.CENTER_HORIZONTAL; + setMargins(tempLayoutParams5, mContext, 24, topMargin, 24, bottomMargin); + tempContainer5.setLayoutParams(tempLayoutParams5); + tempContainer5.setOrientation(LinearLayout.HORIZONTAL); + setPaddings(tempContainer5, mContext, 12, 12, 12, 12); GradientDrawable mDrawable5 = new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, new int[]{accent1, accent1}); mDrawable5.setCornerRadius(dp2px(mContext, 28)); - container5.setBackground(mDrawable5); + tempContainer5.setBackground(mDrawable5); + tempContainer5.setGravity(Gravity.CENTER); + + tempContainer5.addView(time5); + tempContainer5.addView(right5); + + final LinearLayout container5 = new LinearLayout(mContext); + LinearLayout.LayoutParams layoutParams5 = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); + layoutParams5.gravity = Gravity.CENTER; + setMargins(layoutParams5, mContext, 0, topMargin, 0, bottomMargin); + container5.setLayoutParams(layoutParams5); + container5.setGravity(Gravity.CENTER); - container5.addView(time5); - container5.addView(right5); + container5.addView(tempContainer5); return container5; case 6: @@ -446,21 +456,30 @@ public static ViewGroup getClock(Context mContext) { minuteContainer6.addView(minute6); minuteContainer6.addView(minuteText6); + final LinearLayout tempContainer6 = new LinearLayout(mContext); + LinearLayout.LayoutParams tempLayoutParams6 = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); + tempLayoutParams6.gravity = Gravity.CENTER_HORIZONTAL; + setMargins(tempLayoutParams6, mContext, 24, topMargin, 24, bottomMargin); + tempContainer6.setLayoutParams(tempLayoutParams6); + tempContainer6.setGravity(Gravity.CENTER); + tempContainer6.setOrientation(LinearLayout.HORIZONTAL); + setPaddings(tempContainer6, mContext, 20, 20, 20, 24); + GradientDrawable mDrawable6 = new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, new int[]{Color.parseColor("#090909"), Color.parseColor("#090909")}); + mDrawable6.setCornerRadius(dp2px(mContext, 12)); + tempContainer6.setBackground(mDrawable6); + + tempContainer6.addView(dayContainer6); + tempContainer6.addView(hourContainer6); + tempContainer6.addView(minuteContainer6); + final LinearLayout container6 = new LinearLayout(mContext); - LinearLayout.LayoutParams layoutParams6 = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); - layoutParams6.gravity = Gravity.CENTER_HORIZONTAL; - setMargins(layoutParams6, mContext, 24, topMargin, 24, bottomMargin); + LinearLayout.LayoutParams layoutParams6 = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); + layoutParams6.gravity = Gravity.CENTER; + setMargins(layoutParams6, mContext, 0, topMargin, 0, bottomMargin); container6.setLayoutParams(layoutParams6); container6.setGravity(Gravity.CENTER); - container6.setOrientation(LinearLayout.HORIZONTAL); - setPaddings(container6, mContext, 20, 20, 20, 24); - GradientDrawable mDrawable6 = new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, new int[]{Color.parseColor("#090909"), Color.parseColor("#090909")}); - mDrawable6.setCornerRadius(dp2px(mContext, 12)); - container6.setBackground(mDrawable6); - container6.addView(dayContainer6); - container6.addView(hourContainer6); - container6.addView(minuteContainer6); + container6.addView(tempContainer6); return container6; case 7: @@ -553,25 +572,33 @@ public static ViewGroup getClock(Context mContext) { date8.setTypeface(typeface, Typeface.NORMAL); date8.setIncludeFontPadding(false); ViewGroup.MarginLayoutParams dateParams8 = new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.WRAP_CONTENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT); - setMargins(dateParams8, mContext, 0, -10 + lineHeight, 0, 0); + setMargins(dateParams8, mContext, 0, -16 + lineHeight, 0, 0); date8.setLayoutParams(dateParams8); + final LinearLayout tempContainer8 = new LinearLayout(mContext); + LinearLayout.LayoutParams tempLayoutParams8 = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); + tempLayoutParams8.gravity = Gravity.CENTER_HORIZONTAL; + tempContainer8.setLayoutParams(tempLayoutParams8); + tempContainer8.setGravity(Gravity.CENTER); + tempContainer8.setOrientation(LinearLayout.VERTICAL); + setPaddings(tempContainer8, mContext, 40, 24, 40, 24); + GradientDrawable mDrawable8 = new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, new int[]{textColor, textColor}); + mDrawable8.setCornerRadius(dp2px(mContext, 24)); + mDrawable8.setAlpha(50); + tempContainer8.setBackground(mDrawable8); + + tempContainer8.addView(day8); + tempContainer8.addView(clock8); + tempContainer8.addView(date8); + final LinearLayout container8 = new LinearLayout(mContext); - LinearLayout.LayoutParams layoutParams8 = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); - layoutParams8.gravity = Gravity.CENTER_HORIZONTAL; + LinearLayout.LayoutParams layoutParams8 = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); + layoutParams8.gravity = Gravity.CENTER; setMargins(layoutParams8, mContext, 0, topMargin, 0, bottomMargin); container8.setLayoutParams(layoutParams8); container8.setGravity(Gravity.CENTER); - container8.setOrientation(LinearLayout.VERTICAL); - setPaddings(container8, mContext, 40, 24, 40, 24); - GradientDrawable mDrawable8 = new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, new int[]{textColor, textColor}); - mDrawable8.setCornerRadius(dp2px(mContext, 24)); - mDrawable8.setAlpha(50); - container8.setBackground(mDrawable8); - container8.addView(day8); - container8.addView(clock8); - container8.addView(date8); + container8.addView(tempContainer8); return container8; } diff --git a/app/src/main/res/drawable-v24/ic_xposed_depth_wallpaper.xml b/app/src/main/res/drawable-v24/ic_xposed_depth_wallpaper.xml new file mode 100644 index 000000000..93e3712d3 --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_xposed_depth_wallpaper.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/app/src/main/res/layout/activity_xposed_depth_wallpaper.xml b/app/src/main/res/layout/activity_xposed_depth_wallpaper.xml new file mode 100644 index 000000000..67128fe84 --- /dev/null +++ b/app/src/main/res/layout/activity_xposed_depth_wallpaper.xml @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_xposed_lockscreen_clock.xml b/app/src/main/res/layout/activity_xposed_lockscreen_clock.xml index 558329bd0..893828184 100644 --- a/app/src/main/res/layout/activity_xposed_lockscreen_clock.xml +++ b/app/src/main/res/layout/activity_xposed_lockscreen_clock.xml @@ -64,49 +64,6 @@ - - - - - - - - - - - - - - Add custom clock on QS panel Lockscreen Clock Add custom clock on lockscreen + Depth Wallpaper + Show iOS like depth wallpaper Background Chip Add colored chip behind clock Others @@ -530,6 +532,15 @@ White Text Force all colors to be white + + Enable Depth Wallpaper + Show iOS like depth wallpaper\nMust use custom lockscreen clock + Foreground Image + Foreground image for depth wallpaper + Background Image + Background image for depth wallpaper + This feature is currently in beta stage. So bugs are expected.\n\nKnown Bugs:\n• Clock is not shown on AOD.\n• Tapping on lockscreen makes the wallpaper jump. + Status Bar Statusbar Clock Chip @@ -714,6 +725,7 @@ Installation skipped. Some features may not function properly. Imported settings successfully Exported settings successfully + Selected successfully Update Available