Code Monkey home page Code Monkey logo

libwidgetinfo's Introduction

libwidgetinfo

This is an Objective-C and TypeScript API that provides useful data to widgets running in WKWebViews.

The Objective-C layer provides all required extensions to WKWebView necessary to provide such data, and automatically injects the TypeScript API into said webviews.

It is built around a multi-process model:

WKWebView <-> SpringBoard (or whatever else) <-> daemon

iOS 10 and higher is supported.

Backwards Compatibility

Support for the following older widget data libraries is as follows:

  • InfoStats 2: all functionality provided by the library itself, but no arbitrary calls on e.g. SpringBoard objects
  • Widget Weather: all functionality, via interposing the loading of widgetweather.xml
  • XenInfo: all functionality, implemented in the TypeScript API layer

Current Issues

This is currently only built for Xen HTML to integrate with. Using it in other tweaks really doesn't work right now; it'll lead to at least two instances of the daemon running, and class name clashes inside applications. You'll also have issues with dpkg trying to overwrite libwidgetinfo.js.

However, if Xen HTML is not installed, everything will be happy.

Layout

Anything running inside the process hosting a WKWebView is in lib.

TypeScript API lives in lib/middleware.

The daemon subfolder contains everything that runs out-of-process.

Usage

This project can be bundled by doing the following:

  1. Link libwidgetinfo.a, liblogger.a and libobjcipc.a to the main tweak .dylib
  2. Add the following to your constructor in the tweak:
%ctor {
    // If WidgetWeather is present, defer to it
    if ([[NSFileManager defaultManager] fileExistsAtPath:@"/Library/MobileSubstrate/DynamicLibraries/WWRefresh.dylib"]) {
        [XENDWidgetWeatherURLHandler setHandlerEnabled:NO];
    }
    
    // Set filesystem logging as required
    [XENDLogger setFilesystemLoggingEnabled:YES];
    
    // Initialise library
    [XENDWidgetManager initialiseLibrary];
    
    %init();
}
  1. Create a wrapper binary for libwidgetinfodaemon.a, and setup main() as follows:
#import "libwidgetinfo/daemon/Connection/XENDIPCDaemonListener.h"

int main (int argc, const char * argv[]) {
    return libwidgetinfo_main_ipc();
}
  1. Link liblogger.a and libobjcipc.a to the daemon wrapper binary

  2. Link daemon/frameworks/IOKit.tbd to the daemon wrapper binary

  3. Add a LaunchDaemon plist to /Library/LaunchDaemons/ in the end .deb, with the example contents from daemon/launchd.plist.

  4. Compile the TypeScript layer:

    • Install npm and yarn
    • cd to libwidgetinfo/lib/Middleware
    • Run yarn package
    • Copy libwidgetinfo/lib/Middleware/build/libwidgetinfo.js to /Library/Application Support/Widgets/ in the end .deb
  5. Generate documentation:

    • Install npm and yarn
    • cd to libwidgetinfo/lib/Middleware
    • Run yarn docs
    • Generated docs are then inside libwidgetinfo/lib/Middleware/build/docs

Testbed

The Testbed Xcode project allows for running libwidgetinfo in a Simulated mode.

This works out of the box, but you will need to update ViewController.m to point to a widget on your local filesystem.

Third-party Software

This project makes use of the following:

Licensing

libwidgetinfo is available under the AGPLv3.

libwidgetinfo's People

Contributors

dependabot[bot] avatar matchstic avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

yungmichael

libwidgetinfo's Issues

Units are incorrect for hybrid British

In the weather provider, the TWC model incorrectly chooses between metric and imperial for distances/speeds.

It may also return km/h instead of mph.

This is for the case of hybrid units, such as for the UK.

Stock JS Location API

This one is a little bit of a special case - the Weather provider gives a location every 15 minutes or so, which can then be hooked up to the stock JS API for location

Required steps:

  • Interpose the stock JS API for location
  • Monitor for weather data changes, and treat them as location changes

Resources/Statistics provider

Required steps:

  • Port over RAM/battery stuff from previous works
  • Give some proper love to the physical total count - that's broken in XenInfo's implementation, maybe check Exo

Wallpaper provider

This would allow a developer to get both the homescreen and lockscreen wallpapers... Preferably the whole picture (If iOS even saves that) and the zoomed in one, the one the actual phone uses.

I'd think that the whole picture would be available for wallpaper with perspective zoom enabled, but I honestly have no clue...

Weather provider

Required steps:

  • Figure out how to sidestep Weather.framework
  • Setup reasonable auto-updater that pauses when device is locked
  • Add data parser for Weather API
  • Hook up to Location data provider to fetch new data when the user changes significant location
  • Document TypeScript layer with available data

Media provider

Required steps:

  • Research into MediaRemote.framework across iOS 10 to 13 for below steps
  • Add entitlements required to subscribe to media events, and to send them
  • Setup notifications from the framework to react on media events
  • Add millisecond-based update interval in TypeScript layer to avoid overhead of always sending the elapsed time of the current track
  • Setup URL handler for loading artwork

Debugging improvements

To improve debugging, the following should be implemented:

  • Logging of console message to filesystem from widgets
  • Debug options in Settings to: turn on/off global WW3 override, etc

[iOS 14] Music fails to update in some cases

Music data in widgets fails to update when:

  • setting widget for the first time from XenHTML settings
  • widget is on the homescreen and play music for the first time from any app
  • make any change from the widget setting and place it again

It updates when:

  • from the app pause then play the song
  • using volume buttons
  • from the control center
  • when the song changes

Support for Smart Battery Cases (Battery interface)

Support for smart battery cases in the battery interface, both it's percentage and it's design capacity, actual capacity and maybe even it's model number. The model number could also be added to the device's battery info...

Time provider

This is to be a data provider that handles time-related tasks. This includes:

  • Retrieving the current time
  • Helpers functions to format Date objects
  • A “tick” observer, which fires once per second (useful to implement a simple clock)

Integrate with Riba.js

To provide fancy features like so:

<p>{ WidgetInfo.media.data.isPlaying }</p>

I'll be integrating with Riba.js. This will need:

  • Adding as a dependency to the TypeScript layer
  • Setting up with a reasonable global context from which to bind onto elements
  • Documentation for users

XenInfo support

Required steps:

  • Weather compatibility
  • Media compatibility
  • Events compatibility
  • Reminders compatibility
  • Alarms compatibility
  • Statusbar compatibility
  • Battery compatibility
  • System compatibility

Notifications provider

Required steps:

  • Figure out how to observe bulletin center
  • Implement said observation
  • Implement support for posting bulletins

InfoStats 2 support

Required steps:

  • Implement static pre-processor
  • Setup URL loading for the *Stats.txt files

Add compatibility for:

  • Weather API
  • Media API
  • System API
  • Pedometer API
  • Calendar API
  • Location API
  • Telephony API

IPC stuff

Using libobjcipc for this.

Issues:

  • connections not torn down correctly. Seems that input and output streams stay captured, and maybe leak file handles?

Bluetooth Statistics

Is your feature request related to a problem? Please describe.
Not related to a problem. Just couldn't find anyway to get Bluetooth statistics from xenhtml

Describe the solution you'd like
XenHTML API with basic Bluetooth Statistics (Bluetooth names, battery levels, etc.)

Describe alternatives you've considered
Tried checking XenHTML, XenInfo and InfoStats2 docs. Couldn't find anything related to Bluetooth

Additional context
Was trying to make LS Widget that shows battery of connected BT devices but couldn't find any documentation or anything about Bluetooth statistics

Weather localisation fails

Apple's code makes use of the following to do string localisation:

r15 = [[NSBundle bundleForClass:[WeatherPreferences class]] retain];
rbx = [[r15 localizedStringForKey:@"MAJOR_EVENT_FORMAT" value:@"" table:@"WeatherFrameworkLocalizableStrings"] retain];

This is fine for applications that include localisations, but fails in widgetinfod because that does not expose any localisations.

This will likely need a hook into NSLocale's stuff to fix.

CORS proxy

Add a CORS proxy as part of the network provider.

Requirements:

  • Should be implemented as a provider method call
  • Hook XMLHTTPRequest to do requests via the provider
  • Same for fetch()

Slightly extend file system API to read/write JSON settings

The Filesystem API can be used for widget developers to write their own settings UI.

Helper functionality for this should be offered, and also give example plus links to this in the config docs.

These helpers would write to the user’s preferences folder, which can be backed up.

Respect Low Power Mode better

The following changes should be undertaken when Low Power Mode is active:

  • Weather provider should change its update interval to every 30 mins

Applications provider

Required steps:

  • Generate application list from LSApplicationWorkspace (see ReProvision)
  • Monitor for application state changes: installing, installed, deleted, and anything from uicache
  • Implement user alert for deleting an application
  • Set up URL handler for application icon loading

Daemon fails to initialise right after boot

Testing shows that after a reboot, a widget just has to be restarted from scratch to work properly again (e.g., toggle on/off in settings). its possible that loading from cached values totally fails right after a reboot, leading to the API inside existing widgets to not start correctly.

e.g., an LS widget fails to show right after a reboot, but is visible after locking the device again.

Additionally, commands to e.g. change tracks from a widget reach the daemon and run, but some state changes do not appear in widgets until after a respring (irregardless of if the widget is restarted).

To test this, try force-disabling data from remote providers. It seems related to no real data being available in widgets beyond initial startup.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.