Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Some suggestions for future releases #153

Open
twaik opened this issue Oct 26, 2020 · 36 comments
Open

Some suggestions for future releases #153

twaik opened this issue Oct 26, 2020 · 36 comments

Comments

@twaik
Copy link

twaik commented Oct 26, 2020

Hi, Preetam @pdsouza . What's up?
I have some notes about future MaruOS releases. I hope they will be usefull.

I had some time to analize MaruOS commits and found out that MaruOS is:

0. MaruOS structure
  1. AOSP/LineageOS.
  2. Patches for framework/native that allow us to drop external keyboard and mouse events.
  3. Patches for framework/native allowing us to lock NativeBuffer and use them in another process.
  4. Patches for dynamic mirroring of Android/Debian and QuickSettings tile for them.
  5. Patches to use DisplayManager.DisplayListener to detect external display connected.
  6. Maru Desktop settings that let us manage container.
  7. LineageOS statistics, software info and updater service removed.
  8. LXC+Debian distro generator.
  9. Mflinger for passing graphics from Debian to offscreen.
  10. Some other patches.
  1. Debian container.
    A. You can patch useradd/adduser to add every single user created inside container to all needed Android groups to avoid permissions problems. This will fix issues like no socket permission for sql servers.
    B. You can place all MaruOS scripts and patches applied to Debian in blueprint builder in .deb packages. It will let us update Debian part separately from Android part.
    C. You can use apt pinning to disallow replacing your packages with most recent versions from Debian official repos.
    D. At the moment the default username/password are maru/maru.
    OEM vendors use DebianInstaller/Ubiquiti/Calamares to personalize build on first startup. You can use them or add some settings for that in app from item 2.
    E. I/We can write some systemtray menus to control wireless connections (WiFi, BT, Mobile Data, GPS, Hotspot mode, Flight mode), show Android notifications (smth likebKDE Connect ) or other options. Maybe making calls and sms app. These programs will work using some api from a service in item 2's app.
    F. I do not know if it really possible but maybe we can try to make Android apps windows appear in Xorg using freeform feature. Maybe we will need to patch framework. Or maybe system service will be enough for that ( Add a MobilePhone View #2 ).
    G. We can ovverride logout/shut down/reboot actions and make them restart or shut down only a container.
  2. Graphics and input.
    At the moment you are using mflinger as graphics output, Xorg with udev hotplugging enabled, xf86-video-dummy driver and input drivers for external input. And a set of patches to enable/disable input drop for Android, external display connection detection, other stuff.
    I think it can be replaced with one simple system service. All of it.
    You are using Xorg with udev because it can detect hotplugged input devices.
    Mflinger is cool, but it is a bit slow. Instead of sending process like X11Client=>Xserver=>Driver=>AndroidSurface you send it like X11Client=>Xserver=>DummyDriver===>X11Client=>AndroidSurface.
    My suggestion is to replace all of it with Android app that:
    A. Has Xorg builtin as jni library. It will be started inside as one of threads.
    B. Has modified xf86-video-dummy driver for graphics output. It will pass an image to native window from item 2.D.
    C. Has modified xf86-input-sparkle driver that will take input events from 2.D.
    D. Android service that starts Xorg in thread and creates SurfaceView that we can pass to modified dummy driver. And, of cource, one more for a cursor.
    Also it will create transparent focusable overlay window that will cover the whole screen. It will catch all input events, filter externals and pass them to Xorg's driver from 2.3. Returning false on all types of events will pass these events to underlying layers.
    E. We can try to use Pointer Capture API to capture mouse and keyboard input and pass them to Debian when a mouse reaches right corner. Something like multiscreen configuration on normal desktops.
    This way user will not need to choose what OS receives external devices input in interactive mode.
    F. Some stuff of items 1.D, 1.E, 1.F.
    G. Wakelock to keep Maru Interactive running and something to disable screen and touch after screen dim timeout (to optimize use of power).
    H. We can use overlay window described in 2.4 as output for Maru Interactive Mode with no need to use external display, google cast, miracast, displaylink or another types of devices. It is a bit complicated because we will also need to implement popup menu with Interactive Mode disable button and Virtual Keyboard caller. And maybe we will need to reimplement xf86-input-synaptics driver to let people use touchscreen as touchpad.
    I. We can keep this app update in the repo we keep debian packages. And install new version if it is available. We will need to use app install permission to update it. Keeping it in Google Play is not recommended because it does not fit to all devices.
  3. Sound. You can build pulseaudio with system as a vendor overlay or use libhybris (5).
  4. Kernel. Even when we using GSI we still need a patched kernel. We can use something like mer-kernel-check to find out if a kernel config fits to MaruOS or not.
  5. Libhybris.
    A.We can patch bionic to let us use EGL/GLES inside container and effectively use it. But we need to check if the patches crash Android and why. Also we can make EGL/GLES packages for Debian. (Bionic patch moves slome TLS slots to let us use libs without Segfaults in glibc container)
    B. If you do not need to use bionic pulseaudio I can write libhybris library that passes Android's SLES to Debian and then we will be able to use Termux's SLES or AAudio sink.

I alredy did implement 2.A, but the project was abandoned and erased because it couldn't be whitelisted in oom killer's settings on Xiaomi and some other devices.
I can implement 1.E, 2.A, 2.B, 2.C, 2.D, 2.E, 2.G, maybe 2.H.
Bionic pulseaudio and SLES/AAudio sink as already implemented, everything you need is to add them to vendor_maruos repo.
Everything else only you can do. Or I can try it when I will have MaruOS compatible device or MaruOS port for one of my devices.

But I have no devices that support external displays, have no displaylink, google cast or miracast adapters. Everything I can do is to make it work with Presentation API which can be shown to Clockworkmod's Screen recording and mirror and Allcast Receiver. I can try to implement Interactive Mode without external screen (as described in 2.H) with ability to use Presentation API (without DisplayManager.DisplayListener). It will let us use Dex Mode even without external display (Windows and Android versions of Dex already implemented it).

If you follow all of these suggestions (maybe except 1.F) you will have compact vendor_maruos repo, patched bionic, some selinux rules patched and rest of the system unchanged. Debian can be deployed on device itself using something automatical like Linux Deploy (opensource) or prebuilt on your build server. And also you will have Debian repository with override and MaruOS specific packages and, of cource, the app update source. Debian update repository can be a simple http server I do not think you will have problems with it.
It will be [almost] clean AOSP/Lineage/etc GSI distro with no need to maintain a full ROM. Device porters will only need to rebuild kernel with some features enabled and disabled kernel module version checking (to keep vendor modules).

About an app (item 2): we need to check if all the types of input events can be dropped by overlay window. The test app does not need to be a system/vendor app, we can use Android SDK to build it. If it fail we need to use another type of dropping (like sending events from inputflinger directly to Xorg). But it is still a solution.

I can split all the list into stages and make git todo list. But I think 0 stage will be testing Android's invisible overlay window capabilities including event dropping.

For now I have no PC but maybe the next week I will have it and will be able to develop.

Let me know if you are in.

@pdsouza
Copy link
Member

pdsouza commented Oct 28, 2020

@twaik Wow, thanks as always for your hard work digging into the source and figuring out how we can make Maru better, especially from the very early days of this project! I really appreciate your support.

Yes, pretty much all of these suggestions would be amazing to have in Maru. Anything we can do to reduce Maru's custom patches and bring it as close as possible to clean AOSP/Lineage with GSI would make this project so much easier to maintain, develop, and port. As I think you already know, nowadays I do not have as much time to work on Maru like I used to in 2016-2017 so these suggestions would make my life much easier 😄.

Speaking of next steps, if you can get a prototype of the Android app with Xorg (2A-2D) working that I can try out I would be very happy to test it out thoroughly on my devices and work with you to get it integrated into Maru's next major release. I think this is a standalone chunk of work that can replace mclient / mflinger, but still use udev and our frameworks patches for input handling. After that's done, we can start looking at 2E, etc. to eliminate our input related patches.

@utzcoz has also done work to separate out our Settings patches into a standalone app that I have yet to merge in (sorry @utzcoz, I will get to it as soon as I get some time!). We are also discussing how we can just download desktop images from our build server instead of shipping it on the system image. So as you can see, we are already pushing in the direction of minimizing our modifications to AOSP / Lineage as much as possible.

By the way, I really hope you can get your hands on at least a Chromecast so you can easily test Maru with whatever test device you have around so you don't need to worry about having wired external display support. If you can get your hands on a cheap used Nexus 5 or HTC10, those devices have good wired external display support and work with Maru right now. But hopefully you can at least pick up a miracast / chromecast adapter for now.

@twaik
Copy link
Author

twaik commented Oct 29, 2020

Bad news. We can not create system overlay which will intercept and filter events before dispatching. That is impossible due to Android's security. Only system services can do that.
Good news. I think we do not need to patch frameworks to drop some devices. It can be done by InputManagerService. I can not use all of it's features without recompiling firmware but I can try to use it like scrcpy does.
The main idea that you can enable or disable input devices on java side. But for this you will need to use background service which will register InputDeviceListener and disable hotplugged input devices while Android is in Maru Interactive Mode.

@twaik
Copy link
Author

twaik commented Oct 29, 2020

Looks like I found a solution.

  1. We can use System Server service. It will require patching frameworks_base, but we will be able to use WindowManagerService.setInputFilter.
  2. The same as 1, but we can use Xposed framework to inject this service to app_process.
  3. Or you can just enable/disable input via InputManagerService and keep udev on Xorg side.

@twaik
Copy link
Author

twaik commented Oct 30, 2020

Another solution is to use libinputflinger used by SystemServer/.InputService to get input inside application. I think writing my own NativeInputManager will be enough. We will be able to disable external input devices in Android InputService and enable them in MaruService with code like that

...
InputManager = (InputManager) Context.getSystemService(Context.INPUT_SERVICE);
...
public void EnterInteractiveMode() {
    InputDevice device = null;
    int [] devices = InputDevice.getDeviceIds();
    for (int i: devices) {
        device = InputDevice.getDevice();
        if (device != null && device.isExternal()) {
            InputManager.disableDevice(i);
            MaruInput.enableDevice(device.getDescriptor()); // Or device.getId() if they will match in both service implementations
        }
    }
}

@utzcoz
Copy link
Member

utzcoz commented Oct 30, 2020

Another solution is to use libinputflinger used by SystemServer/.InputService to get input inside application. I think writing my own NativeInputManager will be enough. We will be able to disable external input devices in Android InputService and enable them in MaruService with code like that

...
InputManager = (InputManager) Context.getSystemService(Context.INPUT_SERVICE);
...
public void EnterInteractiveMode() {
    InputDevice device = null;
    int [] devices = InputDevice.getDeviceIds();
    for (int i: devices) {
        device = InputDevice.getDevice();
        if (device != null && device.isExternal()) {
            InputManager.disableDevice(i);
            MaruInput.enableDevice(device.getDescriptor()); // Or device.getId() if they will match in both service implementations
        }
    }
}

@pdsouza , the @twaik 's solution to remove dynamic input patch from base to a single system service can be a good choice to consider. From the Android 10 code, NativeInputManager.disableDevice can intercept input events of specific device to base level. If it can be done, we will have more compact code for maru features.

@twaik
Copy link
Author

twaik commented Oct 30, 2020

@utzcoz You are right. If you want you can remove dynamic input dropping now and disable input devices from Maru Interactive mode tile code.

@twaik
Copy link
Author

twaik commented Nov 1, 2020

Looks like my phone is bricked :) I've flashed wrong firmware and now it is only vibrating.
I think I will go on developing using virtual machine...

@utzcoz
Copy link
Member

utzcoz commented Nov 2, 2020

@utzcoz You are right. If you want you can remove dynamic input dropping now and disable input devices from Maru Interactive mode tile code.

Okay, I will try it when I have enough free time. And I will give feedback to this issue.

@twaik
Copy link
Author

twaik commented Nov 2, 2020

Hi. I do not have any physical device to test it so I need somebody who have Android 9 device. It should respond to adb shell getevent without Permission Denied. No root required.

  1. Build that using AOSP 9.0 source. MaruInputTest.tar.gz
  2. push it to /data/local/tmp.
  3. adb shell /data/local/tmp/MaruInputTest
  4. Post log of the test here.
  5. Also I need log of adb shell dumpsys input

I can build MaruInputTest on my PC for you, but I need to know target arch (arm64, armhf, x86, x86_64).

@pdsouza
Copy link
Member

pdsouza commented Nov 3, 2020

Another solution is to use libinputflinger used by SystemServer/.InputService to get input inside application. I think writing my own NativeInputManager will be enough. We will be able to disable external input devices in Android InputService and enable them in MaruService with code like that

...
InputManager = (InputManager) Context.getSystemService(Context.INPUT_SERVICE);
...
public void EnterInteractiveMode() {
    InputDevice device = null;
    int [] devices = InputDevice.getDeviceIds();
    for (int i: devices) {
        device = InputDevice.getDevice();
        if (device != null && device.isExternal()) {
            InputManager.disableDevice(i);
            MaruInput.enableDevice(device.getDescriptor()); // Or device.getId() if they will match in both service implementations
        }
    }
}

@pdsouza , the @twaik 's solution to remove dynamic input patch from base to a single system service can be a good choice to consider. From the Android 10 code, NativeInputManager.disableDevice can intercept input events of specific device to base level. If it can be done, we will have more compact code for maru features.

@utzcoz Wow, it would be great if we could use InputManager from the Java layer to do dynamic input switching. I see that we have InputManager.disableInputDevice() available even in Android 9 Pie, which is good! I am happy to work with you to move our input patches to use this approach.

@twaik
Copy link
Author

twaik commented Nov 8, 2020

@pdsouza hi. Looks like I have built bionic version of libX11.so. If you want to merge mclient and mflinger into one program you can use it. It can be the way to avoid pathching frameworks_base to provide copying screen content using GraphicBuffer/Surface hacks.
Also I found that there is SurfaceControl class in Android framework. It can create surfaces and assign layerstack. That means you can use DisplayManager.DisplayListener's onDisplayAdded/onDisplayChanged or to create SurfaceControl with Surface assigned to display's layerstack (displayId = layerStack), or to place SurfaceView on external display using Presentaion API. Surface got from ny of them can be used in mflinger with no need to patch frameworks_base/frameworks_native. But you still need to hack them for tile 👎 .

@twaik
Copy link
Author

twaik commented Nov 8, 2020

Looks like I have Xorg and its dependencies sources that can be built using NDK/AOSP build systems. I still did not test it but it will work. This work is based on old project that worked.
I think we will have something like that:

  1. Java service with Xorg. Xorg needs to be executed in isolated process and it is not recommended to be included into Activity. It will be built like scrcpy or TermuxAm project. We will be able to start it using /usr/bin/system_server with custom CLASSPATH environment variable. That mean it can be run as shell or root user and use all of their privilegies, including crearing surfaces using SurfaceControl (Java or C++), disabling input devices in Android, control WiFi, BT and all of the things that need system privilegies. Also it will be able to detect displays using DisplayManager.DisplayListener.
  2. Regular Android application. It will be able to create QuickSettings tiles and show other stuff. I mean it will be something like GUI for first app. Also it can show something like touchpad/keyboard for Maru Interactive mode even if there is no external devices connected (something like UnifiedRemote basic input mode). Also it can contain tweak settings, container settings (user management or anything else), etc.

@twaik
Copy link
Author

twaik commented Nov 8, 2020

Also I found out that it is possible to add QuickSettings tiles even without modifying system app:

tiles=$(adb shell settings get secure sysui_qs_tiles)
adb shell settings put secure sysui_qs_tiles $(tiles),MaruTile1,MaruTile2,etc...

We even can execute these comands on first startup on device. Or just put a button in app (2) which will trigger comandexecuting in Java service (1).

PS. I checked getting and putting qs tiles. The put comand allows us to add or remove tiles in real time, without reboot.

@twaik
Copy link
Author

twaik commented Nov 15, 2020

Well, my Xorg build (NDK) works. I checked it with x11vnc+fluxbox+pcmanfm. I am starting to write input and output drivers.
Maybe it will be much easier and correct to use termux build system to build Xorg and it's dependencies. And this will allow us to change configure flags if needed and update Xorg separately from ROM. Actually we can keep all the changes inside this build process (but not selinux patches and kernel patches).

@twaik
Copy link
Author

twaik commented Nov 15, 2020

@pdsouza @utzcoz Can you please build Android Emulator x86_64 image for me? It will be much easier to check if everything works well on "real" MaruOS ROM.

@twaik
Copy link
Author

twaik commented Feb 21, 2022

About mflinger. Looks like you do not need to create virtual display using modified framework, you can create it using VirtualDisplay API and then draw on it using Surface (you can pull and push GraphicBuffers and draw on them, use dequeue/queueBuffer on surface to draw GraphicBuffer). VirtualDisplay's backend is Surface too so it can be drawn on external display.

@utzcoz
Copy link
Member

utzcoz commented Feb 21, 2022

About mflinger. Looks like you do not need to create virtual display using modified framework, you can create it using VirtualDisplay API and then draw on it using Surface (you can pull and push GraphicBuffers and draw on them, use dequeue/queueBuffer on surface to draw GraphicBuffer). VirtualDisplay's backend is Surface too so it can be drawn on external display.

@twaik Thanks for pointing out it. I have used VirtualDisplay with Surface many times last year, it's a great approach to remove current frameworks modification(if we use system permissions or system uid to remove potential VirtualDisplay restrictions). Let's mark it as a queuing work for 0.7.

@twaik
Copy link
Author

twaik commented Feb 21, 2022

A. You can patch useradd/adduser to add every single user created inside container to all needed Android groups to avoid permissions problems. This will fix issues like no socket permission for sql servers.

About that. You can write a daemon which adds all users mentioned in container's /etc/passwd to all Android permission groups on start. Also it should follow /etc/passwd's events using inotify. It will help to fix #180 and some issues mentioned in google groups.
If you are trying to replace patched framework with separate app you can start this daemon as a thread in this app...

@twaik
Copy link
Author

twaik commented Apr 4, 2022

Hi guys. I found out that you cloned android_platform_frameworks_native repo only to add function Surface::lockWithHandle to access protected class member field. but I do not think it is really neccesary. I think you can declare class based on Surface and static_castify existing Surface instance to this new class. And this code will look like:

class ASurface : public Surface {
	buffer_handle_t* getLockedBufferHandle(void) {
		if (mLockedBuffer == 0) {
			ALOGE("ASurface::getLockedBufferHandle failed, no locked buffer");
			return NULL;
		}

		return &mLockedBuffer->handle;
	}
}

...

        sp<SurfaceControl> sc = state->surfaces[idx];
        sp<Surface> _s = sc->getSurface(); /* ** */
        ASurface* s = static_cast<ASurface*>(_s->get()); /* ** */

        ANativeWindow_Buffer outBuffer;
        buffer_handle_t handle;
// --   status_t err = s->lockWithHandle(&outBuffer, &handle, NULL);
        status_t err = s->lock(&outBuffer, NULL);
        if (err != 0) {
            ALOGE("failed to lock buffer");
        } else if (handle->numFds < 1) {
            ALOGE("buffer handle does not have any fds");
        } else {
            /* all is well */
/* ++ */    outBuffer = *(s->getLockedBufferHandle());
            response.buffer.width = outBuffer.width;
            response.buffer.height = outBuffer.height;
            response.buffer.stride = outBuffer.stride;
            response.buffer.bits = NULL;
            response.result = 0;

            return sendfd(sockfd, (void *)&response,
                sizeof(response), handle->data[0]);
        }

I think after adding this code you can get rid of android_platform_frameworks_base.
@utzcoz What do you think?

@twaik
Copy link
Author

twaik commented Apr 4, 2022

About android_platform_frameworks_base repo.
Major changes:

A few Android.bp's and SystemServiceRegistry.java ( + added some *.aidl and *.java files).
They were changed to build PerspectiveService with system jars and start it as system service. I think we can build them as a part of vendor_maruos repo. You can add your service name to config_deviceSpecificSystemServices which is defined here. It can be overridden on overlay. Jar files can be added to SYSTEMSERVERCLASSPATH or BOOTCLASSPATH but I am not sure how exactly. *.so files with jni bindings can be loaded with simple System.loadLibrary call.

Context.java.
It is modified to add perspective service name as a constant.

Displaymanager.java, DisplayManagerGlobal.java, IDisplayManager.aidl, Display.java, DisplayManagerService.java, LocalDisplayAdapter.java and a lot of *.xml's.
All of them are modified to create layerstack for mflinger which is mirrored to external display when it is connected, to catch display connection events and handle it.
I found one interesting thing: mirroring is being disabled if some app starts projecting content on a display so we can use this.
You can create system service (or service contained in *.apk, not really neccesary to run it as root) which creates virtual display using VirtualDisplay API, starts mflinger (as jni) with Surface which is rendered to VirtualDisplay, creates and handles DisplayManager.DisplayListener and starts drawing on external display. We can try to avoid using VirtualDisplay and draw Surface directly on external display but I think we should keep it for the case if we want to use custom resolutions (I am not sure if we can scale Surface on external display).

After finishing all of those we can get rid of cloned android_platform_frameworks_base repo.

@utzcoz
Copy link
Member

utzcoz commented Apr 5, 2022

@twaik Thanks for those brilliant insights. The MaruOS has a long-term plan to move most of modifications of frameworks/base and frameworks/native to a single system app, and prepare Linux's window combination with Android's native window. I have did some early work on MaruSettings, and I think you have noticed it. IMO, we can remove modifications from frameworks/native and many of frameworks/base when working for a single system app from my previous experience about ROM customization. We really appreciate your suggestion to module MaruOS, thanks again for it. We decide to continue maru-0.7 at the mid of this year, and let's discuss more about when and which part of those great suggestion will be envolved into maru-0.7 or later versions. :)

@twaik
Copy link
Author

twaik commented May 9, 2022

@utzcoz what do you think about using Magisk to patch existing system instead of patching AOSP/Lineage?

@utzcoz
Copy link
Member

utzcoz commented May 11, 2022

@utzcoz what do you think about using Magisk to patch existing system instead of patching AOSP/Lineage?

@twaik Thanks for this suggestion. Sorry, I'm not familiar with Magisk, could you explain more about which part that Magisk can patch, and which part not? Thanks.

@twaik
Copy link
Author

twaik commented May 11, 2022

Patching system classpath can be a bit more complicated so we can try to make Magisk module containing needed changes.

@twaik
Copy link
Author

twaik commented Oct 6, 2022

It looks like Magisk is unneeded here, we can simply inject some code using Riru. But it will interfere with current LSPosed implementation.

@twaik
Copy link
Author

twaik commented Dec 15, 2022

About mflinger. I advised to use VirtualDisplay API. I think we can use it not.
No need to modify Displaymanager.java, DisplayManagerGlobal.java, IDisplayManager.aidl, Display.java, DisplayManagerService.java, LocalDisplayAdapter.java and a lot of *.xml's. No need to use VirtualDisplay API
There is a way to use Java process with JNI without extracting native libraries somewhere (it was discussed here). That means we can track external displays connection (in Java) and manage Surfaces (in JNI) in the same module.

About SystemServiceRegistry.
No need to modify SystemServiceRegistry.java, config_deviceSpecificSystemServices, SYSTEMSERVERCLASSPATH or BOOTCLASSPATH.
It is not needed to start PerspectiveService service in zygote. It is possible to simply start service in other Java process started app_process with root permissions (maybe in init). After that you can register that using ServiceManager.addService.

I think all of it can be placed in vendor image. But I am not sure about init.rc.

Also you can pack mflinger (Java/native version started using app_process), PerspectiveService (started with app_process too, maybe in the same starting sequence, and registered with ServiceManager.addService), MaruSettings, other additions to the same *.apk.
After that it will be possible to install Maru on any ROM with single update.zip containing this apk, lxc data, perspectived, kernel, blueprints/guest os. I do not think Selinux policies will be needed because all services will be started as root. init.rc should be edited within update.zip update sequence.

@twaik
Copy link
Author

twaik commented Feb 6, 2023

I have good news. I found out that XCB can be connected with fd (using xcb_connect_to_fd call, we can connect directly to $PREFIX/tmp/.X11-unix/X0 and pass opened unix socket fd to xcb). And XCB is can be compiled with Android build system. I already can build it with Gradle+CMake (to pack it to regular android app). Only non-standard thing we should do is to invoke python script to generate some code in C.
I am planning to re-write mclient in c++ using XCB, then integrate mflinger. Also I am planning to pack xcb+mclient+mflinger as JNI and draw screen image directly to SurfaceView's using regular ANativeWindow_lock+ANativeWindow_unlockAndPost. What do you think (I really want to know)?

P.S. One more question. Will you mind if I use this code in my app?

@twaik
Copy link
Author

twaik commented Feb 6, 2023

After implementing this you only will need to move PerspectiveService to separate *.apk file (like this) if you want to stop patching android_platform_frameworks_base.

@twaik
Copy link
Author

twaik commented Feb 7, 2023

I already have some code which will add to server exact resolution of screen. And user will be able to choose smaller resolution in the case if screen is hidpi. Link.

@twaik
Copy link
Author

twaik commented Mar 6, 2023

I have a code to implement full client with changing resolution and polling with android ndk (CMake buildscript) if you need. It can be modified to do the same thing mflinger does. Check termux-x11 project. The only thing I do not implement is polling cursor coordinates, but it can be implemented easily.

@twaik
Copy link
Author

twaik commented Mar 6, 2023

@utzcoz

@utzcoz
Copy link
Member

utzcoz commented Mar 7, 2023

@twaik Thanks for your work and suggestions. I will learn it this weekend and give response here.

@twaik
Copy link
Author

twaik commented Mar 8, 2023

Pay attention that with this you can use it even without lockWithHandle solution. Or if you want you can use this and send this fd directly to X server using xcb_shm_attach_fd call (and it will be a bit faster, because it will be zero-copy solution).
Also you can check how we did hardware acceleration inside Termux project. Link. It is much better then using llvmpipe.

@pdsouza
Copy link
Member

pdsouza commented Mar 9, 2023 via email

@utzcoz
Copy link
Member

utzcoz commented Mar 19, 2023

About mflinger. I advised to use VirtualDisplay API. I think we can use it not.
No need to modify Displaymanager.java, DisplayManagerGlobal.java, IDisplayManager.aidl, Display.java, DisplayManagerService.java, LocalDisplayAdapter.java and a lot of *.xml's. No need to use VirtualDisplay API
There is a way to use Java process with JNI without extracting native libraries somewhere (it was discussed here). That means we can track external displays connection (in Java) and manage Surfaces (in JNI) in the same module.

Sound great. I used VirtualDisplay to implement many great features. I think we can leverage it to reduce modifications for physical display. But we "might" some modifications to system apps or SurfaceFlinger to show it on the screen or the external display.

It is not needed to start PerspectiveService service in zygote. It is possible to simply start service in other Java process started app_process with root permissions (maybe in init). After that you can register that using ServiceManager.addService.

Sound great too. PerspectiveService is only a system service.

After that it will be possible to install Maru on any ROM with single update.zip containing this apk, lxc data, perspectived, kernel, blueprints/guest os. I

There are some SELinux and Kernel configs limitations that other ROM can't run MaruOS directly without any custom modifications.

I am planning to re-write mclient in c++ using XCB, then integrate mflinger. Also I am planning to pack xcb+mclient+mflinger as JNI and draw screen image directly to SurfaceView's using regular ANativeWindow_lock+ANativeWindow_unlockAndPost. What do you think (I really want to know)?

For X11, it sound great. SurfaceView + VirtualDisplay is a great pair to reduce modifications and implement the same function. I agree to try this approach. Looking forward to your experiment. I think it can be a great step to separate MaruOS from frameworks.

After implementing this you only will need to move PerspectiveService to separate *.apk file (like this) if you want to stop patching android_platform_frameworks_base.

I agree this method too. We can rename MaruSettings to MaruOS or similar name, and merge PerspectiveService into it with SystemService.addService.

@twaik Thanks for your suggestions.

@twaik
Copy link
Author

twaik commented Mar 19, 2023

SurfaceView + VirtualDisplay is a great pair to reduce modifications and implement the same function. I agree to try this approach. Looking forward to your experiment. I think it can be a great step to separate MaruOS from frameworks.

Using SurfaceView is enough to reduce modifications. You can simply use existing surface with ANativeWindow_setBuffersGeometry and hardware scaler will do rest of work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants