Monday, March 9, 2026

Privacy Policy for Wreda Keyboard

Privacy Policy

Wreda Keyboard

Wreda Keyboard is a simple offline keyboard application designed to provide basic typing functionality and the ability to emulate human typing. The application is free to use and does not include advertisements.

Your privacy is important to us. This Privacy Policy explains how the application handles user data.

Data Collection

Wreda Keyboard does not collect, store, or transmit personal data.

The application does not collect:

  • Names

  • Email addresses

  • Phone numbers

  • Typed text

  • Device identifiers

  • IP addresses

  • Location data

All operations performed by the application occur locally on the user’s device.

Keyboard Input

As an Input Method Editor (IME), Wreda Keyboard processes text input entered by the user in order to provide keyboard functionality.

All typed text is processed locally on the device only and is not stored, logged, transmitted, or shared with the developer or any third parties.

Clipboard Access

Wreda Keyboard may read text from the device clipboard only when the user has copied text from another application.

This clipboard content may be used by the keyboard to support the human typing emulation feature, which simulates typing behavior using text copied by the user.

Clipboard data:

  • is processed locally on the device

  • is not stored by the application

  • is not transmitted outside the device

Internet Usage

Wreda Keyboard does not require an internet connection.

The application does not communicate with external servers.

Advertising and Analytics

Wreda Keyboard does not include advertising.

The application does not use analytics services, tracking tools, or third-party SDKs.

Data Sharing

The application does not share any user data with third parties.

Data Storage

Wreda Keyboard does not store personal or typed data on the device or on any external servers.

Children’s Privacy

Wreda Keyboard does not knowingly collect personal information from children under the age of 13.

Changes to This Privacy Policy

This Privacy Policy may be updated if the application functionality changes. Any updates will be reflected in the updated version of this document.

Contact

If you have any questions about this Privacy Policy, you may contact:

dedetoke@gmail.com




Sunday, March 1, 2026

Debian 13: upgrading bios

Is it possible to upgrade bios from Debian, since the most manufacture only provide bios upgrade under windows environment? In the past it is impossible. But today, it can for some systems. Here is the way to check and upgrade bios from bios. you need root or sudo, i use root user.

Install software

# apt install fwupd

Check your bios

# dmidecode 3.6
Getting SMBIOS data from sysfs.
SMBIOS 3.4.0 present.

Handle 0x0000, DMI type 0, 26 bytes
BIOS Information
    Vendor: LENOVO
    Version: JNCN52WW(V2.12)
    Release Date: 10/04/2024 <- your release date
    Address: 0xE0000
    Runtime Size: 128 kB
    ROM Size: 32 MB
    Characteristics:
        PCI is supported
        BIOS is upgradeable
        BIOS shadowing is allowed
        Boot from CD is supported
        Selectable boot is supported
        EDD is supported
        Japanese floppy for NEC 9800 1.2 MB is supported (int 13h)
        Japanese floppy for Toshiba 1.2 MB is supported (int 13h)
        5.25"/360 kB floppy services are supported (int 13h)
        5.25"/1.2 MB floppy services are supported (int 13h)
        3.5"/720 kB floppy services are supported (int 13h)
        3.5"/2.88 MB floppy services are supported (int 13h)
        8042 keyboard services are supported (int 9h)
        CGA/mono video services are supported (int 10h)
        ACPI is supported
        USB legacy is supported
        BIOS boot specification is supported
        Targeted content distribution is supported
        UEFI is supported
    BIOS Revision: 1.52
    Firmware Revision: 1.52

Handle 0x001C, DMI type 13, 22 bytes
BIOS Language Information
    Language Description Format: Long
    Installable Languages: 4
        en|US|iso8859-1
        fr|FR|iso8859-1
        ja|JP|unicode
        zh|TW|unicode
    Currently Installed Language: en|US|iso8859-1

To show product name and version

# cat /sys/class/dmi/id/product_name
82SB
# cat /sys/class/dmi/id/product_version
IdeaPad Gaming 3 15ARH7

Check device  

# fwupdmgr get-devices
LENOVO 82SB

├─AMD Ryzen 5 7535HS with Radeon Graphics:
│ │   Device ID:          4bde70ba4e39b28f9eab1628f9dd6e6244c03027
│ │   Vendor:             Advanced Micro Devices, Inc.
│ │   GUIDs:              52f8f9af-1ca9-5352-bef4-ceb232c888a5 ← CPUID\PRO_0&FAM_19&MOD_44
│ │                       e94372a3-3ffb-5d1c-a579-c415b7313e52 ← CPUID\PRO_0&FAM_19&MOD_44&STP_1
│ │   Device Flags:       • Internal device
│ │ 
│ ├─Secure Processor:
│ │     Device ID:        c54ab0237d7a8db8c717b68e0be78e4374a2a079
│ │     Current version:  00.28.00.71
│ │     Bootloader Version: 00.28.00.71
│ │     Vendor:           Advanced Micro Devices, Inc. (PCI:0x1022)
│ │     GUID:             9844da3e-1df2-52fe-9413-d4378af6221e ← PCI\VEN_1022&DEV_1649
│ │     Device Flags:     • Internal device
│ │                       • Can tag for emulation
│ │   
│ └─System Management Unit (SMU):
│       Device ID:        db0330716216c629bb2c07256e5d018f499eb6ce
│       Summary:          Microcontroller used within CPU/APU program 4
│       Current version:  69.63.0
│       Vendor:           Advanced Micro Devices, Inc.
│       GUID:             79307ae6-a2ea-52e1-bf56-6abbaf3547ad ← /sys/devices/platform/AMDI0007:00
│       Device Flags:     • Internal device
│                         • Can tag for emulation
│     
├─GA107 [GeForce RTX 2050]:
│     Device ID:          ce4c74a5188d5b9cdb1e72ed32dad2d313c1c999
│     Current version:    a1
│     Vendor:             NVIDIA Corporation (PCI:0x10DE)
│     GUID:               68e82ae9-e3f2-5996-ba6b-9054136e6d65 ← PCI\VEN_10DE&DEV_25AD
│     Device Flags:       • Internal device
│                         • Cryptographic hash verification is available
│                         • Can tag for emulation
│   
├─Micron MTFDKCD512QFM-1BD1AABLA:
│     Device ID:          04e17fcf7d3de91da49a163ffe4907855c3648be
│     Summary:            NVM Express solid state drive
│     Current version:    1002V3LN
│     Vendor:             Micron Technology Inc (PCI:0x1344)
│     Serial Number:      22453C44BE0D
│     Problems:           • Device requires AC power to be connected
│     GUIDs:              84b40af9-5392-5d04-ab7a-92c6ecd85f9f ← NVME\VEN_1344&DEV_5413
│                         518236e8-44dc-5c54-86bf-8ab9c098cd5e ← NVME\VEN_1344&DEV_5413&SUBSYS_13441100
│                         2f40d3c1-c50e-5e7f-aa6c-9cbef7c3679f ← Micron MTFDKCD512QFM-1BD1AABLA
│     Device Flags:       • Internal device
│                         • System requires external power source
│                         • Needs a reboot after installation
│                         • Device is usable for the duration of the update
│                         • Updatable
│                         • Can tag for emulation
│   
├─System Firmware:
│ │   Device ID:          c74868c50fe146f6d80a0978b8140db47f89c95a
│ │   Summary:            UEFI System Resource Table device (updated via NVRAM)
│ │   Current version:    1879441490
│ │   Minimum Version:    1380122624
│ │   Vendor:             LENOVO (DMI:LENOVO)
│ │   Update State:       Success
│ │   Problems:           • Device requires AC power to be connected
│ │   GUID:               b287b6c8-7a87-48d7-9316-da7a121e91c6
│ │   Device Flags:       • Internal device
│ │                       • System requires external power source
│ │                       • Needs a reboot after installation
│ │                       • Cryptographic hash verification is available
│ │                       • Device is usable for the duration of the update
│ │                       • Updatable
│ │   Device Requests:    • Message
│ │ 
│ ├─Ideapad Products:
│ │     Device ID:        6924110cde4fa051bfdc600a60620dc7aa9d3c6a
│ │     Summary:          UEFI Platform Key
│ │     Current version:  0
│ │     Vendor:           Unknown
│ │     GUID:             a5ace873-b5ff-5d82-9051-52a46d71b6a4 ← UEFI\CRT_D1FA4BAE5073E699B7D04455F4F1126530BD69A4
│ │     Device Flags:     • Internal device
│ │                       • Cryptographic hash verification is available
│ │                       • Can tag for emulation
│ │   
│ ├─UEFI Signature Database:
│ │ │   Device ID:        0352a8acc949c7df21fec16e566ba9a74e797a97
│ │ │   Device Flags:     • Internal device
│ │ │ 
│ │ └─Windows Production PCA:
│ │       Device ID:      ea9d4960094c43d107b919fe44941f2c774f84df
│ │       Current version: 2011
│ │       Vendor:         Microsoft (UEFI:Microsoft)
│ │       GUIDs:          675d2184-6c9a-59f1-a6f1-3c229b5dbb79 ← UEFI\VENDOR_Microsoft&NAME_Microsoft-Windows-Production-PCA
│ │                       1a84097f-714e-51b7-b293-9a803c98bb1d ← UEFI\CRT_CBBBF4B136DB90D11FD37A4A9B2106973AECC095
│ │       Device Flags:   • Internal device
│ │                       • Updatable
│ │                       • Signed Payload
│ │                       • Can tag for emulation
│ │     
│ └─UEFI dbx:
│       Device ID:        362301da643102b9f38477387e2193e57abaa590
│       Summary:          UEFI revocation database
│       Current version:  20230301
│       Minimum Version:  20230301
│       Vendor:           UEFI:Microsoft
│       Install Duration: 1 second
│       GUID:             f8ba2887-9411-5c36-9cee-88995bb39731 ← UEFI\CRT_A1117F516A32CEFCBA3F2D1ACE10A87972FD6BBE8FE0D0B996E09E65D802A503&ARCH_X64
│       Device Flags:     • Internal device
│                         • Updatable
│                         • Needs a reboot after installation
│                         • Cryptographic hash verification is available
│                         • Device is usable for the duration of the update
│                         • Only version upgrades are allowed
│                         • Signed Payload
│                         • Can tag for emulation
│     
├─TPM:
│     Device ID:          1d8d50a4dbc65618f5c399c2ae827b632b3ccc11
│     Current version:    6.20.0.6
│     Vendor:             Advanced Micro Devices, Inc. (TPM:AMD)
│     GUIDs:              9305de1c-1e12-5665-81c4-37f8e51219b8 ← TPM\VEN_AMD&DEV_0001
│                         78a291ae-b499-5b0f-8f1d-74e1fefd0b1c ← TPM\VEN_AMD&MOD_AMD
│                         65a3fced-b423-563f-8098-bf5c329fc063 ← TPM\VEN_AMD&DEV_0001&VER_2.0
│                         5e704f0d-83cb-5364-8384-f46d725a23b8 ← TPM\VEN_AMD&MOD_AMD&VER_2.0
│     Device Flags:       • Internal device
│                         • System requires external power source
│                         • Needs a reboot after installation
│                         • Device can recover flash failures
│                         • Full disk encryption secrets may be invalidated when updating
│                         • Signed Payload
│                         • Can tag for emulation
│   
├─UEFI Device Firmware:
│     Device ID:          e78fe7874aa72b14bc3138165829a0f046b925e4
│     Summary:            UEFI System Resource Table device (updated via NVRAM)
│     Current version:    0
│     Minimum Version:    1
│     Vendor:             DMI:LENOVO
│     Update State:       Success
│     Problems:           • Device requires AC power to be connected
│     GUID:               a9898afa-ef58-48fe-b09a-f476afce467c
│     Device Flags:       • Internal device
│                         • System requires external power source
│                         • Needs a reboot after installation
│                         • Device is usable for the duration of the update
│                         • Updatable
│     Device Requests:    • Message
│   
└─UEFI Device Firmware:
      Device ID:          cb1be209f9d53fed715391d7dcb894ba4d874719
      Summary:            UEFI System Resource Table device (updated via NVRAM)
      Current version:    3378443
      Vendor:             DMI:LENOVO
      Update State:       Success
      Problems:           • Device requires AC power to be connected
      GUID:               e18d48f3-8ed4-484e-8e01-cc33572399ff
      Device Flags:       • Internal device
                          • System requires external power source
                          • Needs a reboot after installation
                          • Device is usable for the duration of the update
                          • Updatable
      Device Requests:    • Message

Refresh firmware meta-data

# fwupdmgr refresh --force
Updating lvfs
Downloading…             [************************************** ]

Successfully downloaded new metadata: Updates have been published for 0 of 5 local devices

Perform upgrade

# fwupdmgr get-updates
Devices with no available firmware updates: 
 • Micron MTFDKCD512QFM-1BD1AABLA
 • System Firmware
 • UEFI Device Firmware
 • UEFI Device Firmware
 • KEK CA
 • OK Certificate
 • UEFI CA
 • UEFI dbx
 • Windows Production PCA
No updatable devices

 

Thursday, February 26, 2026

Android java: using sqliteopenhelper pattern code

Using additional Room may increase size of application, means more lines required to executed. implement SQLiteOpenHelper rather then using Room Library, will give you more controll data for performance.
Please note that: 

  • deleting column require minimum sqlite version 3.35.0
  • every android vendor may use different version of sqlite, it is possible uses lower then sqlite version 3.35.0 

Suppose you have application that has published and install in world wide, with sqlite database 

version 1 

  1. id (auto increment)
  2. name

version 2

  1. id (auto increment)
  2. name
  3. datebirth

version 3

  1. id (auto increment)
  2. name
  3. datebirth
  4. address

The code

public class MySQLHelper extends SQLiteOpenHelper {

    private static final String dbName = "[your_database_file_name].db";
    private static final int DATABASE_VERSION = 3; // MUST HAVE


    /*
     * constructor
     */
    public MySQLHelper(@Nullable Context context) {
        // name String: of the database file, or null for an in-memory database
        super(context, dbName, null, DATABASE_VERSION);
    }

    /*
     * only call once when database not exist 
     */
    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {
        createDB(sqLiteDatabase);
    }

    /*
     * use latest latest database structure
     */
    private void createDB(SQLiteDatabase sqLiteDatabase) {
        String CREATE_TABLE = "CREATE TABLE user (" +
                "id INTEGER PRIMARY KEY AUTOINCREMENT, " +
                "name TEXT, " +
                "datebirth TEXT, " +
                "address TEXT)";
        db.execSQL(CREATE_TABLE);
    }

    /*
     * only call when database exist 
     */
    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int curVersion, int newVersion) {
        if (oldVersion < 2) {
            db.execSQL("ALTER TABLE user ADD COLUMN datebirth TEXT");
        }

        if (oldVersion < 3) {
            db.execSQL("ALTER TABLE user ADD COLUMN address TEXT");
        }
    }

    /*
     * only call when database exist
     * delete / drop column only available to sqlite 3.35.0 or higher
     * it will crash run on lower sqlite version
     * NOT RECOMMENDED TO USE DOWNGRADE
     */
    @Override
    public void onDowngrade(SQLiteDatabase sqLiteDatabase, int curVersion, int newVersion) {
        ...
    }

if you wish to drop column on device with sqlite lower then 3.35.0 use rename table, create table, copy values and drop table. Don't use lower DATABASE_VERSION, just increase version and remove unused column using onUpgrade. Here is the example code onUpgrade() to remove column:

public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    if (oldVersion < 2) {
        db.execSQL("ALTER TABLE my_table ADD COLUMN datebirth TEXT");
    }
    if (oldVersion < 3) {
        db.execSQL("ALTER TABLE my_table ADD COLUMN address TEXT");
    }
    if (oldVersion < 4) {
        // --- STEP 1: Rename current table ---
        db.execSQL("ALTER TABLE my_table RENAME TO temp_table");

        // --- STEP 2: Create new table without 'address' ---
        db.execSQL("CREATE TABLE my_table ("
                + "id INTEGER PRIMARY KEY,"
                + "name TEXT,"
                + "datebirth TEXT)");

        // --- STEP 3: Copy data (only the columns you want to keep) ---
        db.execSQL("INSERT INTO my_table (id, name, datebirth) " +
                   "SELECT id, name, datebirth FROM temp_table");

        // --- STEP 4: Remove the old table ---
        db.execSQL("DROP TABLE temp_table");
    }

 

Monday, February 23, 2026

Android java: boot on boot receiver

This is a table on all android boot where on receive event trigger your application:

State Security Status getMySharedPreferences Result Download/ Folder Access
1. SIM PIN OS Kernel is paused Receiver won't run. Blocked.
2. Pattern/PIN Direct Boot Mode Success! (With your new code) Fail. (Shared Storage is still encrypted)
3. No Security Full Boot Success! Success!
4. SIM + Pattern Double Lock Receiver won't run. Blocked.    

Base of state of boot above, here is onReceive() skeleton code

public class MyBootReceiver extends BroadcastReceiver {

    // simple state to prevent double running
    private static boolean isRunning = false;

    @Override
    public void onReceive(Context context, Intent intent) {
        // state of boot device
        String action = intent.getAction();
        if (action == null) return;

        switch (action) {
            case Intent.ACTION_LOCKED_BOOT_COMPLETED:
                // STAGE 1: Phone just turned on, PIN screen is visible.
                // DO: Check SharedPreferences (Device Protected) only.
                break;

            case Intent.ACTION_USER_UNLOCKED:
                // STAGE 2: User just entered PIN.
                // DO: Access Contacts and Folders now.
                break;

            case Intent.ACTION_BOOT_COMPLETED:
                // STAGE 3: System is fully initialized.
                if (isRunning) return; // Prevent double execution
        
        isRunning = true;
                // DO: Final cleanup or scheduling.
                break;

            case "android.intent.action.ALARM_MATCHED": // Your custom alarm action
                // DO: The actual backup if triggered by AlarmManager.
                break;
        }

 Permission and service for on boot receiver in android manifest 

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
...
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
...

...
    <application
...
        <receiver
            android:name=".MyBootReceiver"
            android:enabled="true"
            android:exported="true"
            android:directBootAware="true"
            >
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
                <action android:name="android.intent.action.LOCKED_BOOT_COMPLETED"/>
                <action android:name="android.intent.action.USER_UNLOCKED" />
            </intent-filter>
        </receiver>
...

Recommended boot receiver (gemini ai)

public class MyBootReceiver extends BroadcastReceiver {

    // simple state to prevent double running
    private static boolean isRunning = false;

    @Override
    public void onReceive(Context context, Intent intent) {
        // state of boot device
        String action = intent.getAction();
        if (action == null) return;

        switch (action) {
            case Intent.ACTION_LOCKED_BOOT_COMPLETED:
                // Phone is locked. Use Device Protected Storage to schedule the next alarm.
                // Do NOT try to read contacts or write files here.

                break;

            case Intent.ACTION_USER_UNLOCKED:
            case Intent.ACTION_BOOT_COMPLETED:
                // FULL BOOT / UNLOCKED.
                if (isRunning) return; // Prevent double execution
        
        isRunning = true;
                // This is where you run your overdue check logic.
                break;

            case "android.intent.action.ALARM_MATCHED":
                // DO something, it is the time
                break;
        }


    }

 

 

 

Android java: Work Manager and Alarm Manager

Java Android Scheduling: Work Manager and Alarm Manager

WorkManager: 

  • Constraints: You can specify conditions like "only run when charging" or "only on Wi-Fi".
  • Persistence: Tasks survive device reboots and app crashes.
  • Backward Compatibility: It automatically chooses the best underlying API (JobScheduler, AlarmManager, etc.) based on the device's API level.
  • Limitation: It does not guarantee exact timing. The system may delay execution to optimize battery life. 

AlarmManager

  • Precision: Can wake the device from Doze mode to trigger a notification exactly when scheduled.
  • Lifecycle Independent: Operates outside your app's lifecycle once set.
  • It is resource-intensive because it wakes the device.
  • It does not support execution constraints (like network requirements).
  • For long-running tasks triggered by an alarm, Google recommends handing off the work to WorkManager from the alarm's BroadcastReceiver.  
Feature  WorkManager AlarmManager
Timing Deferrable (inexact) Precise (exact)
Guaranteed? Yes, even after reboot Not inherently (must reset on reboot)
Constraints Battery, Network, Storage None (time-only)
Power Efficiency High (optimized by OS) Low (wakes device)
Minimum Interval 15 minutes for periodic work None (can be immediate)
Supported Version Known stable on Android 13+ All