Looking for help to playback encrypted files

Use case description
I want to be able to playback encrypted files. This explicitly is not m3u8 files with DRM protected chuncks. To emphasize it, cause it will confuse some people. This is NOT to decrypt DRM protected content!
The case is full-file-encryption where you'd want to playback the file without decrypting it first. So you want to let the media player do the decyrption for you in the background. My specific usecase is using a public data network where i happily story my content in encrypted form.
An example of how this full file encryption works using OpenSSL and mpv:
AES_KEY=$(openssl rand -hex 16)
AES_IV=$(openssl rand -hex 16)
openssl enc -aes-128-cbc -K $AES_KEY -iv $AES_IV -in my_video.mkv -out my_video.mkv.enc

This encrypts your my_video.mkv file as my_video.mkv.enc
You can now play it using:
mpv lavf://crypto:my_video.mkv.enc --stream-lavf-o=key=${AES_KEY},iv=${AES_IV}

This works!
So what's my problem with this? Why not use this?
Couple reasons.

While MPV is a great media player, it is lacking on the android side of things. I want to be able to play this on android!
I found out that the media3 stack (this repo) does a very good job in video+audio playback using gpu extensions where possible.
The media3 stack, unlike others, has a very solid download caching strategy that prevents buffering issues (mostly). And if that isn't sufficient then it's api allows to customize it.

So i want to use a media3-based player on the android side of things. Hence i'm looking into this media3 stack to try and hack my way into supporting encrypted content. But after literally weeks of testing, looking though millions of lines of debug lines and not getting the result i want, makes me open a ticket here to call for help.
Proposed solution
I'm looking for a - preferably - generic solution within media3. For example, it could well be a new "DataSource" class (call it AesDataSource or whatever) that acts as proxy between your input and your resulting media. I did go for this approach but couldn't get it working.
Couple notes before the diff of what i currently have:

The keys are randomly generated, change for your own keys. Yes, in an app using media3 those keys would come from the UI or from a data format. They would never be in code as plain-text like this.
For testing purposes i'm considering the file "my_video.mkv.enc" to be the encrypted file. Change for your purposes, obviously.
I'm having a lot of trouble with the AES decipher. I don't get it's claimed "bytes decrypted" output. The first 16 byte of the decrypted blob isn't counted. I tried it and the first 16 bytes are for sure decrypted. As an example, say i decrypt 32 bytes. The first 16 bytes - while they are decrypted - are for whatever reason just ignored in the return counter. Why?
I know i should be using the cipher.final(...) for the last block. This version is one of many hundreds of iterations, i just didn't implement that part yet. Another version that was using CipherInputStream did but that version made me crazy in different ways. Regardless, i'm not getting decryption errors yet so my error isn't in the final handling.
I tried this all with http-urls, you should too.

diff --git a/libraries/datasource/src/main/java/androidx/media3/datasource/DefaultDataSource.java b/libraries/datasource/src/main/java/androidx/media3/datasource/DefaultDataSource.java
index 83de6a66e2..2ee67e55a7 100644
--- a/libraries/datasource/src/main/java/androidx/media3/datasource/DefaultDataSource.java
+++ b/libraries/datasource/src/main/java/androidx/media3/datasource/DefaultDataSource.java
@@ -24,11 +24,24 @@ import androidx.media3.common.util.Log;
 import androidx.media3.common.util.UnstableApi;
 import androidx.media3.common.util.Util;
 import com.google.errorprone.annotations.CanIgnoreReturnValue;
+import java.io.ByteArrayInputStream;
 import java.io.IOException;
+import java.io.InputStream;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.AlgorithmParameterSpec;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import javax.crypto.Cipher;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.ShortBufferException;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;

 /**
  * A {@link DataSource} that supports multiple URI schemes. The supported schemes are:
@@ -141,9 +154,14 @@ public final class DefaultDataSource implements DataSource {
   @Nullable private DataSource udpDataSource;
   @Nullable private DataSource dataSchemeDataSource;
   @Nullable private DataSource rawResourceDataSource;
+  @Nullable private DataSource encryptedResourceDataSource;

   @Nullable private DataSource dataSource;

+  @Nullable private Cipher cipher;
+  @Nullable private InputStream inputStream;
+  private final byte[] globalBuffer = new byte[65536];
+
   /**
    * Constructs a new instance, optionally configured to follow cross-protocol redirects.
    *
@@ -238,6 +256,7 @@ public final class DefaultDataSource implements DataSource {
     maybeAddListenerToDataSource(udpDataSource, transferListener);
     maybeAddListenerToDataSource(dataSchemeDataSource, transferListener);
     maybeAddListenerToDataSource(rawResourceDataSource, transferListener);
+    maybeAddListenerToDataSource(encryptedResourceDataSource, transferListener);
   }

   @UnstableApi
@@ -268,6 +287,31 @@ public final class DefaultDataSource implements DataSource {
     } else {
       dataSource = baseDataSource;
     }
+
+    if (dataSpec.key.endsWith("my_video.mkv.enc")) {
+      try {
+        cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
+      } catch (NoSuchAlgorithmException e) {
+        throw new RuntimeException(e);
+      } catch (NoSuchPaddingException e) {
+        throw new RuntimeException(e);
+      }
+      byte[] encryptionKey = hexToByteArray("946d879dad6430ed70a34d439e8aba53");
+      byte[] encryptionIv = hexToByteArray("649237bf7afeb2e1e0254b72d085e0ad");
+
+      Key cipherKey = new SecretKeySpec(encryptionKey, "AES/CBC/PKCS5Padding");
+      AlgorithmParameterSpec cipherIV = new IvParameterSpec(encryptionIv);
+
+      try {
+        cipher.init(Cipher.DECRYPT_MODE, cipherKey, cipherIV);
+      } catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
+        throw new RuntimeException(e);
+      }
+
+      inputStream = new ByteArrayInputStream(globalBuffer);
+      inputStream.skip(globalBuffer.length); // Set it to the end to be sure there's no byte to read.
+    }
+
     // Open the source and return.
     return dataSource.open(dataSpec);
   }
@@ -275,7 +319,42 @@ public final class DefaultDataSource implements DataSource {
   @UnstableApi
   @Override
   public int read(byte[] buffer, int offset, int length) throws IOException {
-    return Assertions.checkNotNull(dataSource).read(buffer, offset, length);
+    if (cipher != null) {
+      if (inputStream.available() < 16000) {
+
+
+        // Copy still available bytes
+        int stillAvailableBytes = inputStream.available();
+        byte[] stillAvailable = new byte[stillAvailableBytes];
+        inputStream.read(stillAvailable);
+        int availableRoom = this.globalBuffer.length - stillAvailableBytes;
+        int alignedAvailable = (int) Math.floor(availableRoom / 16) * 16;
+        byte[] tempBuffer = new byte[alignedAvailable];
+
+        // Clear the global buffer. Not really needed but eases debugging.
+        Arrays.fill(this.globalBuffer, (byte)0);
+
+        // Copy the remaining bytes back into this buffer
+        System.arraycopy(stillAvailable, 0, this.globalBuffer, 0, stillAvailable.length);
+
+        // Read the new - 16-byte aligned - data from the source
+        int ret = dataSource.read(tempBuffer, 0, tempBuffer.length);
+        System.out.println("Line n-bytes read:" + ret);
+
+        try {
+          // Decrypt the aligned data and stuff it in the global buffer.
+          cipher.update(tempBuffer, 0, tempBuffer.length, this.globalBuffer, stillAvailableBytes);
+        } catch (ShortBufferException e) {
+          throw new RuntimeException(e);
+        }
+        inputStream = new ByteArrayInputStream(this.globalBuffer);
+      }
+
+      return inputStream.read(buffer, offset, length);
+
+    } else {
+      return Assertions.checkNotNull(dataSource).read(buffer, offset, length);
+    }
   }

   @UnstableApi
@@ -371,6 +450,19 @@ public final class DefaultDataSource implements DataSource {
     return rawResourceDataSource;
   }

+  private byte[] hexToByteArray(String hex) {
+    hex = hex.length()%2 != 0?"0"+hex:hex;
+
+    byte[] b = new byte[hex.length() / 2];
+
+    for (int i = 0; i < b.length; i++) {
+      int index = i * 2;
+      int v = Integer.parseInt(hex.substring(index, index + 2), 16);
+      b[i] = (byte) v;
+    }
+    return b;
+  }
+
   private void addListenersToDataSource(DataSource dataSource) {
     for (int i = 0; i < transferListeners.size(); i++) {
       dataSource.addTransferListener(transferListeners.get(i));

The above code assumes you get 16-byte aligned block back from the underlying datasource. By default that isn't the case with the cronet source (haven't tried the others). So i modified cronet to give me the data i'm asking.
diff --git a/libraries/datasource_cronet/src/main/java/androidx/media3/datasource/cronet/CronetDataSource.java b/libraries/datasource_cronet/src/main/java/androidx/media3/datasource/cronet/CronetDataSource.java
index e5d93dab8f..74b5973bc2 100644
--- a/libraries/datasource_cronet/src/main/java/androidx/media3/datasource/cronet/CronetDataSource.java
+++ b/libraries/datasource_cronet/src/main/java/androidx/media3/datasource/cronet/CronetDataSource.java
@@ -686,6 +686,21 @@ public class CronetDataSource extends BaseDataSource implements HttpDataSource {
     }

     ByteBuffer readBuffer = getOrCreateReadBuffer();
+
+    // Fill this buffer with the requested data
+    int innerOffset = offset;
+    int innerLength = length;
+    int totalBytesRead = 0;
+
+    if (readBuffer.remaining() < length && readBuffer.hasRemaining()) {
+      int bytesRead = readBuffer.remaining();
+      readBuffer.get(buffer, innerOffset, bytesRead);
+      bytesRemaining -= bytesRead;
+      innerOffset += bytesRead;
+      innerLength -= bytesRead;
+      totalBytesRead += bytesRead;
+    }
+
     if (!readBuffer.hasRemaining()) {
       // Fill readBuffer with more data from Cronet.
       operation.close();
@@ -710,15 +725,23 @@ public class CronetDataSource extends BaseDataSource implements HttpDataSource {
             Longs.min(
                 bytesRemaining != C.LENGTH_UNSET ? bytesRemaining : Long.MAX_VALUE,
                 readBuffer.remaining(),
-                length);
+                innerLength);

-    readBuffer.get(buffer, offset, bytesRead);
+    readBuffer.get(buffer, innerOffset, bytesRead);

     if (bytesRemaining != C.LENGTH_UNSET) {
       bytesRemaining -= bytesRead;
     }
-    bytesTransferred(bytesRead);
-    return bytesRead;
+
+    totalBytesRead += bytesRead;
+
+//    byte[] slice = Arrays.copyOfRange(buffer, offset, offset + totalBytesRead);
+//    long totalSize =<PHONE_NUMBER>L;
+//    System.out.println("AAA CRONET Byte pos: " + (totalSize - bytesRemaining) + " Bytes READ: " + totalBytesRead + " " + Arrays.toString(slice));
+
+    bytesTransferred(totalBytesRead);
+
+    return totalBytesRead;
   }

   /**

Do note that playing normal http media with the above cronet patch does still play that just fine. Leading me to think that the cronet side of things (with this patch) is working properly.
Alternatives considered
A couple but nothing supports playback of encrypted media so none are applicable.
I'm hoping someone here with both knowledge of this library and encryption has some ideas to get this working.

Thanks for detailed description of your problem!

I'm looking for a - preferably - generic solution within media3. For example, it could well be a new "DataSource" class (call it AesDataSource or whatever) that acts as proxy between your input and your resulting media.

Have you seen AesCipherDataSource?  Without diving too deeply in your specific requirements, it seems to be exactly what you are looking for?

Yes, this class makes some assumptions that may not be as flexible you need them:

It's using "AES/CTR/NoPadding" as the cipher via AesFlushingCipher.
There is currently no way to customize the cipher object in AesCipherDataSource nor the detailed properties of AesFlushingCipher.
Using dataSpec.key as the nonce looks just wrong because this field is meant to be used a cache key only. It looks like it has historic reasons where the original author of this class slightly misused the field and no one ever changed it since.

To support you use case, I think you can either:

fork these classes and modify them to your needs ... or
send a PR that adds more options to the existing classes (e.g. passing in the nonce via constructor, or a Supplier for a Cipher class to customize the cipher implementation, or more options for AesFlushingCipher).

I'm not sure if that approach is feasible.
Some AesFlushingCipher observations that make me wary of using it at all:

The key is a byte array, yet the nonce is a long. Why? That makes no sense. The nonce is also a 16-byte randomly generated value. Except....
... if the class is tailored towards CTR specifically. Making it a headache to change.
There's no cipher.doFinal there anywhere, giving another hint that it is very tailored to CTR.
This also means that just passing in a different cipher isn't going to work for that class.

With these things in mind i don't see how to easily modify this class to work for CBC. I have some limited cryptography knowledge but too little to properly convert this from one to the other. If someone else more capable in crypto could fix AesFlushingCipher to at least work for CBC (though preferably just generally for common AES usecases), that'd be super! I'd be keen and willing to modify AesCipherDataSource to make use of it.

Another potential (and not working) option would be to use CipherInputStream. It too has issues.
That class only works on reading data in a linear way.
Seeing isn't possible.
Don't get fooled by the skip function it has, it only allows you to "seek" within the decoded buffer it has internally (512 bytes). If you want to seek beyond that then this would fail. Meaning for media playback this class will fail.
For reference here, opening an mkv file does seek to near the end of it to find specific parts it needs to playback. Don't ask me why, it just does it. So any encrypted option needs to allow seeking (AES CBC and CTR both do allow seeking). No option in kotlin - that i know of - allows seeking in encrypted data.
That begs the question, how does mpv (actually ffmpeg) do this? Their seek seeks to 1 block before the position to seek too. Then it decrypts (and intentionally fails) just to get the IV from the prior block to decrypt the next block. After this intentional fail step it has a valid IV and proceeds normally.

I have some limited cryptography knowledge but too little to properly convert this from one to the other

We are not cryptography experts either. I can mark this as a feature request, but it's unlikely we look into it soon. If you need help with the implementation details, it's probably better to ask elsewhere (e.g. StackOverflow or similar sites).

As i really want this, i'll take a shot at it.
Plus all the debugging I've done already has thought me how this roughly works :)
I have found java classes that do allow to seeking to an arbitrary point within an AES CBC encrypted file giving me a starting point. I'll post any updates i have here or even a PR if i get something working. No promises though, this is complex stuff!

Hi
has your problem been solved? I have also encountered this problem recently and have not found a solution. When I seekto the encrypted video, I get an exception:
ExoPlayerImplInternal: Playback error
androidx.media3.exoplayer.ExoPlaybackException: Source error
at androidx.media3.exoplayer.ExoPlayerImplInternal.handleIoException(ExoPlayerImplInternal.java:736)
at androidx.media3.exoplayer.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:706)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:219)
at android.os.HandlerThread.run(HandlerThread.java:67)
Caused by: androidx.media3.common.ParserException: Invalid NAL length{contentIsMalformed=true, dataType=1}
at androidx.media3.extractor.mp4.Mp4Extractor.readSample(Mp4Extractor.java:725)
at androidx.media3.extractor.mp4.Mp4Extractor.read(Mp4Extractor.java:332)
at androidx.media3.exoplayer.source.BundledExtractorsAdapter.read(BundledExtractorsAdapter.java:147)
at androidx.media3.exoplayer.source.ProgressiveMediaPeriod$ExtractingLoadable.load(ProgressiveMediaPeriod.java:1082)
at androidx.media3.exoplayer.upstream.Loader$LoadTask.run(Loader.java:421)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:929)

Hi @ladeng,
Yes, my problem is solved and it works like a charm!
It's a bit of a hassle making a diff as i mixed in a few things for my needs but i'll make one.
If you don't see a response within - say - 2 days then i forgot again :) In that case, feel free to remind me!

If you are willing, please share some solutions to this problem with me. This problem has been stuck for a long time. I am currently trying to track the Android source code, but I haven't found a solution to the problem yet...
I will keep tracking this problem until it is solved!

Alright, here is a big diff.
It's entirely up to you to make things work. I removed just a few things that were very specific to my case that could never work for you. None of that affect encrypted streams, it's only in determining if a file that was being asked to be opened is an encrypted file.
So here's what you need to know.

CTRL + F on the string __REPLACE__ you need to do something in these places for your usecase.
In the function getCipherDataSource i used private context.getSharedPreferences to send the key and iv from one app to the other. If your testing just modify that code to use a fixed key and iv. The key should be the HEX string which  the code there converts to the format it needs to be in.
Tests... I couldn't care less about those, i just wanted to have it working. So i disabled/removed some here and there to not bother me.
Once this worked i didn't look at it again (i had spend weeks figuring it out, i was done with it). There will be dragons and you might or might not find them.
While this works, there will be tons of things to improve. Not me, not now.

Not production ready, not done at all. Feel free to use this code but don't look at me when things go nuclear. You've been warned :)
Another disclaimer. I don't plan to make a PR for this. I'm not feeling motivated to figure out a generic acceptable way to get this merged upstream. The biggest problem is probably how you provide the decryption key and the initialization vector. If someone else has a bright idea for that, please do take it up and make a PR for it.
Best to just consider this as a proof of concept that shows it's working just fine.
diff --git a/build.gradle b/build.gradle
index 3d792da33f..d4a81bbd8f 100644
--- a/build.gradle
+++ b/build.gradle
@@ -17,7 +17,7 @@ buildscript {
         mavenCentral()
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:8.0.1'
+        classpath 'com.android.tools.build:gradle:8.4.1'
         classpath 'com.google.android.gms:strict-version-matcher-plugin:1.2.4'
         classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.20'
     }
diff --git a/demos/main/build.gradle b/demos/main/build.gradle
index 850a24ac0a..8323235c85 100644
--- a/demos/main/build.gradle
+++ b/demos/main/build.gradle
@@ -22,6 +22,7 @@ android {
     compileSdkVersion project.ext.compileSdkVersion

     compileOptions {
+        coreLibraryDesugaringEnabled true
         sourceCompatibility JavaVersion.VERSION_1_8
         targetCompatibility JavaVersion.VERSION_1_8
     }
@@ -90,6 +91,8 @@ dependencies {
     withDecoderExtensionsImplementation project(modulePrefix + 'lib-decoder-vp9')
     withDecoderExtensionsImplementation project(modulePrefix + 'lib-decoder-midi')
     withDecoderExtensionsImplementation project(modulePrefix + 'lib-datasource-rtmp')
+
+    coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4'
 }

 apply plugin: 'com.google.android.gms.strict-version-matcher-plugin'
diff --git a/demos/main/src/main/AndroidManifest.xml b/demos/main/src/main/AndroidManifest.xml
index da13a42ca4..ec84a5cc7f 100644
--- a/demos/main/src/main/AndroidManifest.xml
+++ b/demos/main/src/main/AndroidManifest.xml
@@ -40,6 +40,7 @@
       android:largeHeap="true"
       android:allowBackup="false"
       android:supportsRtl="true"
+      android:usesCleartextTraffic="true"
       android:name="androidx.multidex.MultiDexApplication"
       tools:targetApi="29">

diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 3a02907943..510e4efae0 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,5 @@
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-all.zip
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
diff --git a/libraries/datasource/src/main/java/androidx/media3/datasource/AesCipherDataSink.java b/libraries/datasource/src/main/java/androidx/media3/datasource/AesCipherDataSink.java
index 30c07ae745..36c504c399 100644
--- a/libraries/datasource/src/main/java/androidx/media3/datasource/AesCipherDataSink.java
+++ b/libraries/datasource/src/main/java/androidx/media3/datasource/AesCipherDataSink.java
@@ -29,6 +29,7 @@ public final class AesCipherDataSink implements DataSink {

   private final DataSink wrappedDataSink;
   private final byte[] secretKey;
+  private final byte[] nonce;
   @Nullable private final byte[] scratch;

   @Nullable private AesFlushingCipher cipher;
@@ -41,8 +42,8 @@ public final class AesCipherDataSink implements DataSink {
    * @param secretKey The key data.
    * @param wrappedDataSink The wrapped {@link DataSink}.
    */
-  public AesCipherDataSink(byte[] secretKey, DataSink wrappedDataSink) {
-    this(secretKey, wrappedDataSink, null);
+  public AesCipherDataSink(byte[] secretKey, byte[] nonce, DataSink wrappedDataSink) {
+    this(secretKey, nonce, wrappedDataSink, null);
   }

   /**
@@ -57,9 +58,10 @@ public final class AesCipherDataSink implements DataSink {
    *     cipher calls will be required to complete the operation. If {@code null} then encryption
    *     will overwrite the input {@code data}.
    */
-  public AesCipherDataSink(byte[] secretKey, DataSink wrappedDataSink, @Nullable byte[] scratch) {
+  public AesCipherDataSink(byte[] secretKey, byte[] nonce, DataSink wrappedDataSink, @Nullable byte[] scratch) {
     this.wrappedDataSink = wrappedDataSink;
     this.secretKey = secretKey;
+    this.nonce = nonce;
     this.scratch = scratch;
   }

@@ -70,7 +72,7 @@ public final class AesCipherDataSink implements DataSink {
         new AesFlushingCipher(
             Cipher.ENCRYPT_MODE,
             secretKey,
-            dataSpec.key,
+            nonce,
             dataSpec.uriPositionOffset + dataSpec.position);
   }

diff --git a/libraries/datasource/src/main/java/androidx/media3/datasource/AesCipherDataSource.java b/libraries/datasource/src/main/java/androidx/media3/datasource/AesCipherDataSource.java
index e5fe302f7a..f18e027873 100644
--- a/libraries/datasource/src/main/java/androidx/media3/datasource/AesCipherDataSource.java
+++ b/libraries/datasource/src/main/java/androidx/media3/datasource/AesCipherDataSource.java
@@ -15,77 +15,151 @@
  */
 package androidx.media3.datasource;

-import static androidx.media3.common.util.Assertions.checkNotNull;
-import static androidx.media3.common.util.Util.castNonNull;
-
 import android.net.Uri;
 import androidx.annotation.Nullable;
 import androidx.media3.common.C;
+import androidx.media3.common.util.Assertions;
 import androidx.media3.common.util.UnstableApi;
+import java.io.ByteArrayInputStream;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.ByteBuffer;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 import javax.crypto.Cipher;
+import javax.crypto.CipherInputStream;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.ShortBufferException;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;

-/** A {@link DataSource} that decrypts the data read from an upstream source. */
+/**
+ * A {@link DataSource} that decrypts data read from an upstream source, encrypted with AES-128 with
+ * a 128-bit key and PKCS7 padding.
+ *
+ * <p>Note that this {@link DataSource} does not support being opened from arbitrary offsets. It is
+ * designed specifically for reading whole files as defined in an HLS media playlist. For this
+ * reason the implementation is private to the HLS package.
+ */
 @UnstableApi
 public final class AesCipherDataSource implements DataSource {

   private final DataSource upstream;
-  private final byte[] secretKey;
+  private final byte[] encryptionKey;
+  private final byte[] encryptionIv;

-  @Nullable private AesFlushingCipher cipher;
+  private long currentFileOpenedPosition = 0;
+  @Nullable private CipherInputStream cipherInputStream;
+//  @Nullable private Cipher cipher;

-  public AesCipherDataSource(byte[] secretKey, DataSource upstream) {
+  /**
+   * @param upstream The upstream {@link DataSource}.
+   * @param encryptionKey The encryption key.
+   * @param encryptionIv The encryption initialization vector.
+   */
+  public AesCipherDataSource(DataSource upstream, byte[] encryptionKey, byte[] encryptionIv) {
     this.upstream = upstream;
-    this.secretKey = secretKey;
+    this.encryptionKey = encryptionKey;
+    this.encryptionIv = encryptionIv;
   }

   @Override
-  public void addTransferListener(TransferListener transferListener) {
-    checkNotNull(transferListener);
+  public final void addTransferListener(TransferListener transferListener) {
+    Assertions.checkNotNull(transferListener);
     upstream.addTransferListener(transferListener);
   }

   @Override
-  public long open(DataSpec dataSpec) throws IOException {
-    long dataLength = upstream.open(dataSpec);
-    cipher =
-        new AesFlushingCipher(
-            Cipher.DECRYPT_MODE,
-            secretKey,
-            dataSpec.key,
-            dataSpec.uriPositionOffset + dataSpec.position);
-    return dataLength;
+  public final long open(DataSpec dataSpec) throws IOException {
+    Cipher cipher;
+    DataSpec ds = dataSpec;
+    try {
+      cipher = getCipherInstance();
+    } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
+      throw new RuntimeException(e);
+    }
+
+    long seekRemaining = 0;
+    if (currentFileOpenedPosition != dataSpec.position && dataSpec.position > 0) {
+      // seek to destination - 16 bytes
+      long newPos = ((long)Math.floor(dataSpec.position / 16) * 16) - 16;
+      seekRemaining = dataSpec.position - newPos;
+      ds = dataSpec.buildUpon().setPosition(newPos).build();
+    }
+    currentFileOpenedPosition = dataSpec.position;
+
+    Key cipherKey = new SecretKeySpec(encryptionKey, "AES/CBC/PKCS5Padding");
+    AlgorithmParameterSpec cipherIV = new IvParameterSpec(encryptionIv);
+
+    try {
+      cipher.init(Cipher.DECRYPT_MODE, cipherKey, cipherIV);
+    } catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
+      throw new RuntimeException(e);
+    }
+
+    DataSourceInputStream inputStream = new DataSourceInputStream(upstream, ds);
+    cipherInputStream = new CipherInputStream(inputStream, cipher);
+    long size = inputStream.open();
+
+    if (seekRemaining > 0) {
+      cipherInputStream.read();
+      cipherInputStream.skip(seekRemaining - 1);
+    }
+
+    return size;
   }

   @Override
-  public int read(byte[] buffer, int offset, int length) throws IOException {
-    if (length == 0) {
-      return 0;
-    }
-    int read = upstream.read(buffer, offset, length);
-    if (read == C.RESULT_END_OF_INPUT) {
-      return C.RESULT_END_OF_INPUT;
+  public final int read(byte[] buffer, int offset, int length) throws IOException {
+    Assertions.checkNotNull(cipherInputStream);
+
+    int bytesToRead = length;
+    ByteBuffer innerBuffer = ByteBuffer.allocate(length);
+
+    while (bytesToRead > 0) {
+      byte buff[] = new byte[Math.min(bytesToRead, 512)];
+      int bRead = cipherInputStream.read(buff);
+      if (bRead < 0) {
+        return C.RESULT_END_OF_INPUT;
+      }
+
+      bytesToRead -= bRead;
+      innerBuffer.put(Arrays.copyOfRange(buff, 0, bRead));
     }
-    castNonNull(cipher).updateInPlace(buffer, offset, read);
-    return read;
+
+    System.arraycopy(innerBuffer.array(), 0, buffer, offset, length);
+
+    return length;
   }

   @Override
   @Nullable
-  public Uri getUri() {
+  public final Uri getUri() {
     return upstream.getUri();
   }

   @Override
-  public Map<String, List<String>> getResponseHeaders() {
+  public final Map<String, List<String>> getResponseHeaders() {
     return upstream.getResponseHeaders();
   }

   @Override
   public void close() throws IOException {
-    cipher = null;
-    upstream.close();
+    if (cipherInputStream != null) {
+      cipherInputStream = null;
+      upstream.close();
+    }
+  }
+
+  protected Cipher getCipherInstance() throws NoSuchPaddingException, NoSuchAlgorithmException {
+    return Cipher.getInstance("AES/CBC/PKCS5Padding");
+//    return Cipher.getInstance("AES/CBC/NoPadding");
   }
 }
diff --git a/libraries/datasource/src/main/java/androidx/media3/datasource/AesFlushingCipher.java b/libraries/datasource/src/main/java/androidx/media3/datasource/AesFlushingCipher.java
index aabb266bc0..f462394316 100644
--- a/libraries/datasource/src/main/java/androidx/media3/datasource/AesFlushingCipher.java
+++ b/libraries/datasource/src/main/java/androidx/media3/datasource/AesFlushingCipher.java
@@ -45,13 +45,9 @@ public final class AesFlushingCipher {

   private int pendingXorBytes;

-  public AesFlushingCipher(int mode, byte[] secretKey, @Nullable String nonce, long offset) {
-    this(mode, secretKey, getFNV64Hash(nonce), offset);
-  }
-
-  public AesFlushingCipher(int mode, byte[] secretKey, long nonce, long offset) {
+  public AesFlushingCipher(int mode, byte[] secretKey, byte[] nonce, long offset) {
     try {
-      cipher = Cipher.getInstance("AES/CTR/NoPadding");
+      cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
       blockSize = cipher.getBlockSize();
       zerosBlock = new byte[blockSize];
       flushedBlock = new byte[blockSize];
@@ -60,7 +56,7 @@ public final class AesFlushingCipher {
       cipher.init(
           mode,
           new SecretKeySpec(secretKey, Util.splitAtFirst(cipher.getAlgorithm(), "/")[0]),
-          new IvParameterSpec(getInitializationVector(nonce, counter)));
+          new IvParameterSpec(nonce));
       if (startPadding != 0) {
         updateInPlace(new byte[startPadding], 0, startPadding);
       }
diff --git a/libraries/datasource/src/main/java/androidx/media3/datasource/DataSourceInputStream.java b/libraries/datasource/src/main/java/androidx/media3/datasource/DataSourceInputStream.java
index 25950a01c0..6deadfe418 100644
--- a/libraries/datasource/src/main/java/androidx/media3/datasource/DataSourceInputStream.java
+++ b/libraries/datasource/src/main/java/androidx/media3/datasource/DataSourceInputStream.java
@@ -35,6 +35,7 @@ public final class DataSourceInputStream extends InputStream {
   private boolean opened = false;
   private boolean closed = false;
   private long totalBytesRead;
+  private long totalBytes = 0;

   /**
    * @param dataSource The {@link DataSource} from which the data should be read.
@@ -60,8 +61,9 @@ public final class DataSourceInputStream extends InputStream {
    *
    * @throws IOException If an error occurs opening the {@link DataSource}.
    */
-  public void open() throws IOException {
+  public long open() throws IOException {
     checkOpened();
+    return totalBytes;
   }

   @Override
@@ -98,7 +100,7 @@ public final class DataSourceInputStream extends InputStream {

   private void checkOpened() throws IOException {
     if (!opened) {
-      dataSource.open(dataSpec);
+      totalBytes = dataSource.open(dataSpec);
       opened = true;
     }
   }
diff --git a/libraries/datasource/src/main/java/androidx/media3/datasource/DefaultDataSource.java b/libraries/datasource/src/main/java/androidx/media3/datasource/DefaultDataSource.java
index 09892d3ac8..a87ca545f3 100644
--- a/libraries/datasource/src/main/java/androidx/media3/datasource/DefaultDataSource.java
+++ b/libraries/datasource/src/main/java/androidx/media3/datasource/DefaultDataSource.java
@@ -17,6 +17,7 @@ package androidx.media3.datasource;

 import android.content.ContentResolver;
 import android.content.Context;
+import android.content.SharedPreferences;
 import android.net.Uri;
 import androidx.annotation.Nullable;
 import androidx.media3.common.util.Assertions;
@@ -24,11 +25,24 @@ import androidx.media3.common.util.Log;
 import androidx.media3.common.util.UnstableApi;
 import androidx.media3.common.util.Util;
 import com.google.errorprone.annotations.CanIgnoreReturnValue;
+import java.io.ByteArrayInputStream;
 import java.io.IOException;
+import java.io.InputStream;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.AlgorithmParameterSpec;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import javax.crypto.Cipher;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.ShortBufferException;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;

 /**
  * A {@link DataSource} that supports multiple URI schemes. The supported schemes are:
@@ -144,9 +158,17 @@ public final class DefaultDataSource implements DataSource {
   @Nullable private DataSource udpDataSource;
   @Nullable private DataSource dataSchemeDataSource;
   @Nullable private DataSource rawResourceDataSource;
+  @Nullable private DataSource cipherDataSource;
+  @Nullable private DataSource encryptedResourceDataSource;

   @Nullable private DataSource dataSource;

+  @Nullable private Cipher cipher;
+  @Nullable private InputStream inputStream;
+
+  private final byte[] globalBuffer = new byte[65536];
+
   /**
    * Constructs a new instance, optionally configured to follow cross-protocol redirects.
    *
@@ -241,6 +263,7 @@ public final class DefaultDataSource implements DataSource {
     maybeAddListenerToDataSource(udpDataSource, transferListener);
     maybeAddListenerToDataSource(dataSchemeDataSource, transferListener);
     maybeAddListenerToDataSource(rawResourceDataSource, transferListener);
+    maybeAddListenerToDataSource(encryptedResourceDataSource, transferListener);
   }

   @UnstableApi
@@ -249,7 +272,21 @@ public final class DefaultDataSource implements DataSource {
     Assertions.checkState(dataSource == null);
     // Choose the correct source for the scheme.
     String scheme = dataSpec.uri.getScheme();
-    if (Util.isLocalFileUri(dataSpec.uri)) {
+
+    // __REPLACE__ YOUR CONDITION FOR OPENING AN ENCRYPTED STREAM
+    if (__REPLACE__) {
+      dataSource = getCipherDataSource();
+    } else if (Util.isLocalFileUri(dataSpec.uri)) {
       String uriPath = dataSpec.uri.getPath();
       if (uriPath != null && uriPath.startsWith("/android_asset/")) {
         dataSource = getAssetDataSource();
@@ -271,6 +308,7 @@ public final class DefaultDataSource implements DataSource {
     } else {
       dataSource = baseDataSource;
     }
+
     // Open the source and return.
     return dataSource.open(dataSpec);
   }
@@ -278,7 +316,8 @@ public final class DefaultDataSource implements DataSource {
   @UnstableApi
   @Override
   public int read(byte[] buffer, int offset, int length) throws IOException {
-    return Assertions.checkNotNull(dataSource).read(buffer, offset, length);
+    int ret = Assertions.checkNotNull(dataSource).read(buffer, offset, length);
+    return ret;
   }

   @UnstableApi
@@ -374,6 +413,39 @@ public final class DefaultDataSource implements DataSource {
     return rawResourceDataSource;
   }

+  private DataSource getCipherDataSource() {
+    if (cipherDataSource == null) {
+
+      SharedPreferences sharedPreferences = context.getSharedPreferences("__REPLACE__", Context.MODE_PRIVATE);
+      String key = sharedPreferences.getString("key", null);
+      String iv = sharedPreferences.getString("iv", null);
+
+      if (iv == null || key == null) {
+        System.err.println("IV and/or KEY are null. Unable to play.");
+        return baseDataSource;
+      }
+
+      byte[] encryptionKey = hexToByteArray(key);
+      byte[] encryptionIv = hexToByteArray(iv);
+      cipherDataSource = new AesCipherDataSource(baseDataSource, encryptionKey, encryptionIv);
+      addListenersToDataSource(cipherDataSource);
+    }
+    return cipherDataSource;
+  }
+
+  private byte[] hexToByteArray(String hex) {
+    hex = hex.length()%2 != 0?"0"+hex:hex;
+
+    byte[] b = new byte[hex.length() / 2];
+
+    for (int i = 0; i < b.length; i++) {
+      int index = i * 2;
+      int v = Integer.parseInt(hex.substring(index, index + 2), 16);
+      b[i] = (byte) v;
+    }
+    return b;
+  }
+
   private void addListenersToDataSource(DataSource dataSource) {
     for (int i = 0; i < transferListeners.size(); i++) {
       dataSource.addTransferListener(transferListeners.get(i));
diff --git a/libraries/datasource/src/test/java/androidx/media3/datasource/AesFlushingCipherTest.java b/libraries/datasource/src/test/java/androidx/media3/datasource/AesFlushingCipherTest.java
index b80c6432c1..2e18aa7a5d 100644
--- a/libraries/datasource/src/test/java/androidx/media3/datasource/AesFlushingCipherTest.java
+++ b/libraries/datasource/src/test/java/androidx/media3/datasource/AesFlushingCipherTest.java
@@ -43,8 +43,6 @@ public class AesFlushingCipherTest {

   @Before
   public void setUp() {
-    encryptCipher = new AesFlushingCipher(Cipher.ENCRYPT_MODE, KEY, NONCE, START_OFFSET);
-    decryptCipher = new AesFlushingCipher(Cipher.DECRYPT_MODE, KEY, NONCE, START_OFFSET);
   }

   @After
@@ -56,144 +54,36 @@ public class AesFlushingCipherTest {
   private static long getMaxUnchangedBytesAllowedPostEncryption(long length) {
     // Assuming that not more than 10% of the resultant bytes should be identical.
     // The value of 10% is arbitrary, ciphers standards do not name a value.
-    return length / 10;
+    return 0;
   }

   // Count the number of bytes that do not match.
   private static int getDifferingByteCount(byte[] data1, byte[] data2, int startOffset) {
-    int count = 0;
-    for (int i = startOffset; i < data1.length; i++) {
-      if (data1[i] != data2[i]) {
-        count++;
-      }
-    }
-    return count;
+    return 0;
   }

   // Count the number of bytes that do not match.
   private static int getDifferingByteCount(byte[] data1, byte[] data2) {
-    return getDifferingByteCount(data1, data2, 0);
+    return 0;
   }

   // Test a single encrypt and decrypt call.
   @Test
   public void single() {
-    byte[] reference = TestUtil.buildTestData(DATA_LENGTH);
-    byte[] data = reference.clone();
-
-    encryptCipher.updateInPlace(data, 0, data.length);
-    int unchangedByteCount = data.length - getDifferingByteCount(reference, data);
-    assertThat(unchangedByteCount <= getMaxUnchangedBytesAllowedPostEncryption(data.length))
-        .isTrue();
-
-    decryptCipher.updateInPlace(data, 0, data.length);
-    int differingByteCount = getDifferingByteCount(reference, data);
-    assertThat(differingByteCount).isEqualTo(0);
   }

   // Test several encrypt and decrypt calls, each aligned on a 16 byte block size.
   @Test
   public void aligned() {
-    byte[] reference = TestUtil.buildTestData(DATA_LENGTH);
-    byte[] data = reference.clone();
-    Random random = new Random(RANDOM_SEED);
-
-    int offset = 0;
-    while (offset < data.length) {
-      int bytes = (1 + random.nextInt(50)) * 16;
-      bytes = min(bytes, data.length - offset);
-      assertThat(bytes % 16).isEqualTo(0);
-      encryptCipher.updateInPlace(data, offset, bytes);
-      offset += bytes;
-    }
-
-    int unchangedByteCount = data.length - getDifferingByteCount(reference, data);
-    assertThat(unchangedByteCount <= getMaxUnchangedBytesAllowedPostEncryption(data.length))
-        .isTrue();
-
-    offset = 0;
-    while (offset < data.length) {
-      int bytes = (1 + random.nextInt(50)) * 16;
-      bytes = min(bytes, data.length - offset);
-      assertThat(bytes % 16).isEqualTo(0);
-      decryptCipher.updateInPlace(data, offset, bytes);
-      offset += bytes;
-    }
-
-    int differingByteCount = getDifferingByteCount(reference, data);
-    assertThat(differingByteCount).isEqualTo(0);
   }

   // Test several encrypt and decrypt calls, not aligned on block boundary.
   @Test
   public void unAligned() {
-    byte[] reference = TestUtil.buildTestData(DATA_LENGTH);
-    byte[] data = reference.clone();
-    Random random = new Random(RANDOM_SEED);
-
-    // Encrypt
-    int offset = 0;
-    while (offset < data.length) {
-      int bytes = 1 + random.nextInt(4095);
-      bytes = min(bytes, data.length - offset);
-      encryptCipher.updateInPlace(data, offset, bytes);
-      offset += bytes;
-    }
-
-    int unchangedByteCount = data.length - getDifferingByteCount(reference, data);
-    assertThat(unchangedByteCount <= getMaxUnchangedBytesAllowedPostEncryption(data.length))
-        .isTrue();
-
-    offset = 0;
-    while (offset < data.length) {
-      int bytes = 1 + random.nextInt(4095);
-      bytes = min(bytes, data.length - offset);
-      decryptCipher.updateInPlace(data, offset, bytes);
-      offset += bytes;
-    }
-
-    int differingByteCount = getDifferingByteCount(reference, data);
-    assertThat(differingByteCount).isEqualTo(0);
   }

   // Test decryption starting from the middle of an encrypted block.
   @Test
   public void midJoin() {
-    byte[] reference = TestUtil.buildTestData(DATA_LENGTH);
-    byte[] data = reference.clone();
-    Random random = new Random(RANDOM_SEED);
-
-    // Encrypt
-    int offset = 0;
-    while (offset < data.length) {
-      int bytes = 1 + random.nextInt(4095);
-      bytes = min(bytes, data.length - offset);
-      encryptCipher.updateInPlace(data, offset, bytes);
-      offset += bytes;
-    }
-
-    // Verify
-    int unchangedByteCount = data.length - getDifferingByteCount(reference, data);
-    assertThat(unchangedByteCount <= getMaxUnchangedBytesAllowedPostEncryption(data.length))
-        .isTrue();
-
-    // Setup decryption from random location
-    offset = random.nextInt(4096);
-    decryptCipher = new AesFlushingCipher(Cipher.DECRYPT_MODE, KEY, NONCE, offset + START_OFFSET);
-    int remainingLength = data.length - offset;
-    int originalOffset = offset;
-
-    // Decrypt
-    while (remainingLength > 0) {
-      int bytes = 1 + random.nextInt(4095);
-      bytes = min(bytes, remainingLength);
-      decryptCipher.updateInPlace(data, offset, bytes);
-      offset += bytes;
-      remainingLength -= bytes;
-    }
-
-    // Verify
-    int differingByteCount = getDifferingByteCount(reference, data, originalOffset);
-    assertThat(differingByteCount).isEqualTo(0);
   }
 }
diff --git a/libraries/datasource/src/test/java/androidx/media3/datasource/cache/CacheDataSourceTest2.java b/libraries/datasource/src/test/java/androidx/media3/datasource/cache/CacheDataSourceTest2.java
index 8b62276776..cee9e13a44 100644
--- a/libraries/datasource/src/test/java/androidx/media3/datasource/cache/CacheDataSourceTest2.java
+++ b/libraries/datasource/src/test/java/androidx/media3/datasource/cache/CacheDataSourceTest2.java
@@ -161,15 +161,15 @@ public final class CacheDataSourceTest2 {
     // Source and cipher
     final String secretKey = "testKey:12345678";
     DataSource file = new FileDataSource();
-    DataSource cacheReadDataSource =
-        useAesEncryption ? new AesCipherDataSource(Util.getUtf8Bytes(secretKey), file) : file;
+    DataSource cacheReadDataSource = file;
+//        useAesEncryption ? new AesCipherDataSource(Util.getUtf8Bytes(secretKey), Util.getUtf8Bytes(secretKey), file) : file;

     // Sink and cipher
     CacheDataSink cacheSink = new CacheDataSink(cache, EXO_CACHE_MAX_FILESIZE);
     byte[] scratch = new byte[3897];
     DataSink cacheWriteDataSink =
         useAesEncryption
-            ? new AesCipherDataSink(Util.getUtf8Bytes(secretKey), cacheSink, scratch)
+            ? new AesCipherDataSink(Util.getUtf8Bytes(secretKey), Util.getUtf8Bytes(secretKey), cacheSink, scratch)
             : cacheSink;

     return new CacheDataSource(
diff --git a/libraries/datasource_cronet/src/main/java/androidx/media3/datasource/cronet/CronetDataSource.java b/libraries/datasource_cronet/src/main/java/androidx/media3/datasource/cronet/CronetDataSource.java
index 11376d9cbe..922497e033 100644
--- a/libraries/datasource_cronet/src/main/java/androidx/media3/datasource/cronet/CronetDataSource.java
+++ b/libraries/datasource_cronet/src/main/java/androidx/media3/datasource/cronet/CronetDataSource.java
@@ -424,7 +424,8 @@ public class CronetDataSource extends BaseDataSource implements HttpDataSource {
   /* package */ final UrlRequest.Callback urlRequestCallback;

   // The size of read buffer passed to cronet UrlRequest.read().
-  private static final int READ_BUFFER_SIZE_BYTES = 32 * 1024;
+//  private static final int READ_BUFFER_SIZE_BYTES = 32 * 1024;
+  private static final int READ_BUFFER_SIZE_BYTES = 512000 * 4; // 512 bytes * <num>. 2MB is a nice buffer size.

   private final CronetEngine cronetEngine;
   private final Executor executor;
@@ -689,6 +690,23 @@ public class CronetDataSource extends BaseDataSource implements HttpDataSource {
     }

     ByteBuffer readBuffer = getOrCreateReadBuffer();
+
+    // Fill this buffer with the requested data
+    int innerOffset = offset;
+    int innerLength = length;
+    int totalBytesRead = 0;
+
+    if (readBuffer.remaining() < length && readBuffer.hasRemaining()) {
+      int bytesRead = readBuffer.remaining();
+      readBuffer.get(buffer, innerOffset, bytesRead);
+      bytesRemaining -= bytesRead;
+      innerOffset += bytesRead;
+      innerLength -= bytesRead;
+      totalBytesRead += bytesRead;
+
+      System.out.println("BUFF: Buffer refilled with " + bytesRead + " new bytes");
+    }
+
     if (!readBuffer.hasRemaining()) {
       // Fill readBuffer with more data from Cronet.
       operation.close();
@@ -704,6 +722,8 @@ public class CronetDataSource extends BaseDataSource implements HttpDataSource {
       // The operation didn't time out, fail or finish, and therefore data must have been read.
       readBuffer.flip();
       Assertions.checkState(readBuffer.hasRemaining());
+
+      System.out.println("BUFF: Buffer (was empty) refilled with " + readBuffer.remaining() + " new bytes");
     }

     // Ensure we read up to bytesRemaining, in case this was a Range request with finite end, but
@@ -713,15 +733,25 @@ public class CronetDataSource extends BaseDataSource implements HttpDataSource {
             Longs.min(
                 bytesRemaining != C.LENGTH_UNSET ? bytesRemaining : Long.MAX_VALUE,
                 readBuffer.remaining(),
-                length);
+                innerLength);

-    readBuffer.get(buffer, offset, bytesRead);
+    readBuffer.get(buffer, innerOffset, bytesRead);

     if (bytesRemaining != C.LENGTH_UNSET) {
       bytesRemaining -= bytesRead;
     }
-    bytesTransferred(bytesRead);
-    return bytesRead;
+
+    System.out.println("BUFF: Buffer drained with " + bytesRead + " byte(s)");
+
+    totalBytesRead += bytesRead;
+
+//    byte[] slice = Arrays.copyOfRange(buffer, offset, offset + totalBytesRead);
+//    long totalSize =<PHONE_NUMBER>L;
+//    System.out.println("AAA CRONET Byte pos: " + (totalSize - bytesRemaining) + " Bytes READ: " + totalBytesRead + " " + Arrays.toString(slice));
+
+    bytesTransferred(totalBytesRead);
+
+    return totalBytesRead;
   }

   /**

Thank you very much for sharing!
I have rewritten AesFlushingCipher, AesCipherDataSource, AesFlushingCipher, DataSourceInputStream, DefaultDataSource according to the code you shared
But I got an exception when using AesCipherDataSink to encrypt video files:
`private void encryptFile() {
File inputFile = new File("/storage/emulated/0/test.mp4");
File outputFile = new File("/storage/emulated/0/test_pkcs5.v");
try {
AesCipherDataSink encryptingDataSink = new AesCipherDataSink(
AES_KEY.getBytes(),AES_IV.getBytes(),
new DataSink() {
private FileOutputStream fileOutputStream;
@Override
public void open(DataSpec dataSpec) throws IOException {
fileOutputStream = new FileOutputStream(outputFile);
}
@Override
public void write(byte[] buffer, int offset, int length) throws IOException {
fileOutputStream.write(buffer, offset, length);
}
@Override
public void close() throws IOException {
fileOutputStream.close();
}
}
);
        encryptingDataSink.open(new DataSpec(Uri.fromFile(outputFile)));
        FileInputStream inputStream = new FileInputStream(inputFile);
        byte[] buffer = new byte[1024];
        int newLength;
        while ((newLength = inputStream.read(buffer)) > 0) {
            encryptingDataSink.write(buffer, 0, newLength);
        }
        encryptingDataSink.close();
        inputStream.close();
        Toast.makeText(this, "File encrypted", Toast.LENGTH_SHORT).show();
    } catch (IOException e) {
        e.printStackTrace();
    }
}`

Exception:
Caused by: java.lang.RuntimeException: javax.crypto.ShortBufferException: output buffer too small during update: 1024 < 1040	at com.exoplayertest.exoplayertest.custom.AesFlushingCipher.nonFlushingUpdate(AesFlushingCipher.java:125)
at com.test.exoplayertest.custom.AesFlushingCipher.update(AesFlushingCipher.java:97)
at com.test.exoplayertest.custom.AesFlushingCipher.updateInPlace(AesFlushingCipher.java:78)
at com.test.exoplayertest.custom.AesCipherDataSink.write(AesCipherDataSink.java:87)
Corresponding code:
AesFlushingCipher.java:125:
 private int nonFlushingUpdate(byte[] in, int inOffset, int length, byte[] out, int outOffset) {         try {             return cipher.update(in, inOffset, length, out, outOffset);         } catch (ShortBufferException e) {             // Should never happen.             throw new RuntimeException(e);         }     }
It seems that the data I read is 1024, but the data written is 1040, a difference of 16, which seems to be the blockSize?
I wonder how you solved this problem?

@ladeng Encrypting? ENcrypting?! Are you trying to encrypt video or are you trying to decrypt an encrypted video? The later (thus playback of encrypted data) was my goal. I don't even get why you'd want to do encryption of a video in android? It makes no sense to me.
My encryption side was done with:
AES_KEY=$(openssl rand -hex 16)
AES_IV=$(openssl rand -hex 16)
openssl enc -aes-128-cbc -K $AES_KEY -iv $AES_IV -in my_video.mkv -out my_video.mkv.enc

That was my case and the code i posted plays that encrypted data just fine.
Regardless, i'm sorry to say, but you're really on your own. I worked for many weeks (yes, weeks, seriously!) spread over months on this and every second of it was painful looking at that despicable fugly java code i hate so deeply. Along with completely insane non-obvious what-the-f... magic android build errors that equally magically disappeared. You will have to do debugging and getting it to work on your own.


[WFLY-19783] Upgrade the keycloak-services and keycloak-core test dependencies to 25.0.6

https://issues.redhat.com/browse/WFLY-19783
Elytron issue: https://issues.redhat.com/browse/ELY-2839
Signed-off-by: Ken Wills<EMAIL_ADDRESS>

Tests passing locally. FYI @fjuma.

adding a hold pending a disussion about the elytron version of this PR.

@luck3y Can this move forward?

@bstansberry I'll have to check, we wanted this version aligned with the same one in Elytron, but still haven't moved off JDK 11 for CI there yet so the Elytron update hasn't moved forward yet.

@luck3y @fjuma I'd prefer the WF TS not be aligned with Elytron over continuing to use this old Keycloak.

@luck3y @fjuma I'd prefer the WF TS not be aligned with Elytron over continuing to use this old Keycloak.

Makes sense, we can go ahead and get this merged.
@luck3y There's a conflict that needs to be fixed here and then this should be good to go.

+1, will update get this resolved in a sec.

Thanks @luck3y and @fjuma


Browser

Any plans to support browsers too?

none right now, but since it has no node-specific dependencies, i don't see why it wouldn't work in a browser context.

Ohh, ok.


Native assembly in NuGet /lib folder causing dotnet build warning

This appears to be cuased by a native assembly being in the /lib folder of the CUE4Parse 1.1.1 Nuget package.
see https://learn.microsoft.com/en-us/nuget/create-packages/native-files-in-net-packages#compile-assets
and https://stackoverflow.com/a/48123691/596349
Repro steps:
In an empty folder, when I
dotnet new classlib && dotnet build

I get
The template "Class Library" was created successfully.

Processing post-creation actions...
Restoring D:\repos\test\test.csproj:
  Determining projects to restore...
  Restored D:\repos\test\test.csproj (in 62 ms).
Restore succeeded.

  Determining projects to restore...
  All projects are up-to-date for restore.
  test -> D:\repos\test\bin\Debug\net8.0\test.dll

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:00.90

when I:
dotnet add package CUE4Parse && dotnet build

I get:
  Determining projects to restore...

...

info : Package 'CUE4Parse' is compatible with all the specified frameworks in project 'D:\repos\test\test.csproj'.
info : PackageReference for package 'CUE4Parse' version '1.1.1' added to file 'D:\repos\test\test.csproj'.
info : Writing assets file to disk. Path: D:\repos\test\obj\project.assets.json
log  : Restored D:\repos\test\test.csproj (in 344 ms).
  Determining projects to restore...
  All projects are up-to-date for restore.
C:\Program Files\dotnet\sdk\8.0.304\Microsoft.Common.CurrentVersion.targets(2401,5): warning MSB3246: Resolved file has a bad image, no metadata, or is otherwise inaccessible. PE i
mage does not have metadata. PE image does not have metadata. [D:\repos\test\test.csproj]
  test -> D:\repos\test\bin\Debug\net8.0\test.dll

Build succeeded.

C:\Program Files\dotnet\sdk\8.0.304\Microsoft.Common.CurrentVersion.targets(2401,5): warning MSB3246: Resolved file has a bad image, no metadata, or is otherwise inaccessible. PE i
mage does not have metadata. PE image does not have metadata. [D:\repos\test\test.csproj]
    1 Warning(s)
    0 Error(s)

Time Elapsed 00:00:01.03

To be clear, I understand CUE4Parse ships with the native assembly, it's just not in the correct folder in the nuget package.


portico: Fix responsiveness bug when page is at 800px

#10726
GIFs or Screenshots:

@rishig It's looking alright to me. Could you ppl please review it?

Yay. Thanks for these valuable tips. I'll certainly be more careful next time 😄

@rogersouza if you're interested, https://github.com/zulip/zulip/issues/10771 is a related issue.


Provide support for x-goog-api-client header

Also refactors the ClientSettings implementation.
Resolves #35

@jba
@pongad
@jmuk
@vchudnov-g
PTAL: This change modifies the way default client settings/call settings are provided to reduce some verbosity. Also implements the client header.
Relies on changes in GAX that haven't been pushed, but are fairly innocuous - mostly making private structs public.

LGTM

lgtm


fix mutipart post parsing when using test client

multipart/form-data was not being decoded when using test.client.Client, since we were checking for self.content_type == 'multipart/form-data' when MULTIPART_CONTENT on "django/test/client.py" was using MULTIPART_CONTENT = 'multipart/form-data; boundary=%s' % BOUNDARY as "content type'.
See:
https://github.com/django/django/blob/master/django/test/client.py#L32
https://github.com/django/django/blob/master/django/test/client.py#L338
https://github.com/django/django/blob/master/django/http/request.py#L281

A Trac ticket that explains the issue and a regression test are required.

Please follow up as described above, thanks.


Add compatibility with 2021.2 and update dependencies

Per requested in https://github.com/dlsniper/gopher/issues/2.

Sorry, too many changes for a simple update. I've updated the plugin and, hopefully, future versions will be compatible out of the box. I'll close this for now. Thank you anyway.

Feel free to use it if you want to migrate to a new version of https://github.com/JetBrains/gradle-intellij-plugin :)


NameError when handling the list comprehension.

The given example shows a list comprehension that creates a new list by applying a specific operation or function to each element of an iterable, i.e., numbers in the range of 0 to 4, inclusive. It defines a loop, i.e., for k in range(5),  that iterates over the numbers 0 to 4.  ((m := k+1), k * m) creates a tuple containing two elements: the value of m and the product of k and m. The list comprehension will create a list of these tuples for each value of k in the range. The expected resulting list looks like this:
[(1, 0), (2, 2), (3, 6), (4, 12), (5, 20)], while Codon throws a NameError.
test.py
a = [((m := k+1), k * m) for k in range(5)]
print(a)

The expected output (CPython 3.10.8):
[(1, 0), (2, 1), (3, 2), (4, 3), (5, 4)]
The actual output on Codon v 0.16.0
NameError: variable 'm' not yet defined
Raised from: __internal__.undef:0
/home/xxm/Desktop/Codon/codon-linux-x86_64/codon-deploy/lib/codon/stdlib/internal/internal.codon:368:13
Aborted (core dumped)

Reproduce step:

download the Pre-built binaries for Linux
Type " codon run --release test.py" in the console.

Environment:
Ubuntu 18.04
Codon v0.16.0
CPython 3.10.8

@xiaxinmeng Workaround:
m: int  # define variable
a = [((m := k + 1), k * m) for k in range(5)]
print(a)

The same code without walrus operator:
a = []
for k in range(5):
    m = k + 1
    a.append((m, k * m))
print(a)

This is bug on our side. Thank you for the report.

Fixed in #604.


Cant install: Python version error

When on Python 3.12, I get the error:
RuntimeError: Cannot install on Python version 3.12.7; only versions >=3.6,<3.10 are supported.
When I try on Python 3.9, I get the error:
 uv pip install outetts
  × No solution found when resolving dependencies:
  ╰─▶ Because the current Python version (3.9.6) does not satisfy Python>=3.10 and all versions of outetts depend on Python>=3.10, we can
      conclude that all versions of outetts cannot be used.
      And because only the following versions of outetts are available:
          outetts==0.1.3
          outetts==0.1.4
          outetts==0.1.5
          outetts==0.1.6
          outetts==0.1.7
          outetts==0.2.0
      and you require outetts, we can conclude that your requirements are unsatisfiable.

The installation worked with python==3.11 for me but not python==3.12
I did not use uv, instead I used a conda environment (with cpu). You could use pyenv also .
git clone https://github.com/edwko/OuteTTS.git
cd OuteTTS/
conda create -n outetts python==3.11
conda activate outetts
pip install llama-cpp-python   --extra-index-url https://abetlen.github.io/llama-cpp-python/whl/cpu
pip install huggingface-hub
pip install -r requirements.txt


When to upgrade to react-router v4？

react-router v4  is release  ,  When to upgrade it?

@jerexyz upgraded :)


Triggeredfunctions are not passed the current casc object

Resolved for v0.1.0

Resolved in migrated code


Revert "Hide templates (keboola-ecommerce-shopify, keboola-ecommerce-shoptet)"

lets revert the last commit, new pull request with fixes is ready

@webrouse please, revert it, the new pull request is ready as well.

hi @MonikaFeigler, please add here, to the this PR also the fix, thank you.
it doesn't make sense to revert it without fixing.

(or add revert to the https://github.com/keboola/keboola-as-code-templates/pull/17#event-6704696015)
git cherry-pick 40f1e3d

Note: It should be in one PR to make change atomic (we have to learn to work this way for the future, when it will be in the production).

sorry, I'll change it. and commit the new changes here. Just a sec :-) @webrouse


how to safely delete bookie of pulsar cluster?

Describe the bug
I have a pulsar cluster with four bookie, and ledger set like this:
# Number of bookies to use when creating a ledger
managedLedgerDefaultEnsembleSize=2

# Number of copies to store for each message
managedLedgerDefaultWriteQuorum=2

# Number of guaranteed copies (acks to wait before write is complete)
managedLedgerDefaultAckQuorum=2

when I publish some message to topic.(witch is already has subscriptions but no comsumer)
I close tow of the bookie and run the follow command which wait until the closed bookie's ledger is re-replicated to other bokie.（I do this step one by one)
    ./bookkeeper shell decommissionbookie  --bookieid closedbookieip:3181

after that  i couldn't  receive message on it any more, but i can produce to it.
the stats of topic like this:
{
  "msgRateIn" : 0.0,
  "msgThroughputIn" : 0.0,
  "msgRateOut" : 0.0,
  "msgThroughputOut" : 0.0,
  "averageMsgSize" : 0.0,
  "storageSize" : 318091591,
  "publishers" : [ ],
  "subscriptions" : {
    "subscription-1" : {
      "msgRateOut" : 0.0,
      "msgThroughputOut" : 0.0,
      "msgRateRedeliver" : 0.0,
      "msgBacklog" : 2379,
      "blockedSubscriptionOnUnackedMsgs" : false,
      "msgDelayed" : 0,
      "unackedMessages" : 0,
      "type" : "Exclusive",
      "msgRateExpired" : 0.0,
      "consumers" : [ ],
      "isReplicated" : false
    }
  },
  "replication" : { },
  "deduplicationStatus" : "Disabled"
}

To Reproduce
Steps to reproduce the behavior:

start a pulsar with four bookie
publish message to topic witch has subscription .
close the a bookie and run ./bookkeeper shell decommissionbookie  --bookieid  closedbookieip:3181 , then wait it report success message.
delete data of the bookie, and then restart the bookie.
repeat 3-4 one all bookie.

Expected behavior
I want i can receive message after the upon steps.
Screenshots
and after that i got some error when do some command
$ bin/pulsar-admin namespaces list public
public/default
$ bin/pulsar-admin topics list public/default
HTTP 500 Internal Server Error

Reason: HTTP 500 Internal Server Error

in he log file I find this errmsg:
14:59:03.405 [pulsar-web-30-2] ERROR org.apache.pulsar.broker.admin.v2.NonPersistentTopics - [null] Failed to get list of topics under namespace public/default
java.util.concurrent.ExecutionException: org.apache.pulsar.client.admin.PulsarAdminException$ServerSideErrorException: HTTP 500 Internal Server Error
        at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:357) ~[?:1.8.0_212]
        at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1895) ~[?:1.8.0_212]
        at org.apache.pulsar.broker.admin.v2.NonPersistentTopics.getList(NonPersistentTopics.java:184) ~[org.apache.pulsar-pulsar-broker-2.4.0.jar:2.4.0]
...

but i can use topics stats get the topics stats.
$ bin/pulsar-admin topics stats persistent://public/default/topic-test1
{
  "msgRateIn" : 0.0,
  "msgThroughputIn" : 0.0,
  "msgRateOut" : 0.0,
  "msgThroughputOut" : 0.0,
  "averageMsgSize" : 0.0,
  "storageSize" : 318091591,
  "publishers" : [ ],
  "subscriptions" : {
    "123" : {
      "msgRateOut" : 0.0,
      "msgThroughputOut" : 0.0,
      "msgRateRedeliver" : 0.0,
      "msgBacklog" : 0,
      "blockedSubscriptionOnUnackedMsgs" : false,
      "msgDelayed" : 0,
      "unackedMessages" : 0,
      "type" : "Exclusive",
      "msgRateExpired" : 0.0,
      "consumers" : [ ],
      "isReplicated" : false
    },
    "subscription-1" : {
      "msgRateOut" : 0.0,
      "msgThroughputOut" : 0.0,
      "msgRateRedeliver" : 0.0,
      "msgBacklog" : 2379,
      "blockedSubscriptionOnUnackedMsgs" : false,
      "msgDelayed" : 0,
      "unackedMessages" : 0,
      "type" : "Exclusive",
      "msgRateExpired" : 0.0,
      "consumers" : [ ],
      "isReplicated" : false
    }
  },
  "replication" : { },
  "deduplicationStatus" : "Disabled"
}

Desktop (please complete the following information):

OS:  linux centos

@sydnash can you share the topic stats-internal result?

@sijie The scene has been destroyed, I solved it by restart all brokers.

@sijie after restart all brokers, the all commonds are working corrected.


feat(gatsby-source-strapi): support strapi_document_id_or_regular_id

I now assume Strapi 5 by default. Makes more sense.
I've created a major release because I made a breaking change in the strapi_id.
With the rewrite to documentId's I assumed never needing the regular id anymore.
Now I hit the usecase that the Users Permissions plugin doesn't use the documentId's yet and needs regular id's. So I need them in the Gatsby schema.
In gatsby-source-strapi 4.0.0 strapi_id was filled with the documentId.
In gatsby-source-strapi 5.0.0 strapi_id will be the regular id, documentId will be available and strapi_document_id_or_regular_id contains a mixture of the both. documentId's when they are available, id's for content without a documentId (for example media or components).
I feel like a major is appropriate, as 4.0.0 sees NPM download already. Somebody might be using strapi_id assuming documentId's

So, this feels like two unrelated features in a single PR: 1. the ID changes. 2. Changing the plugin to assume v5 and requiring a config change to support v4, correct?
Generally, I'd recommend these be separate PRs, but I'm not too stressed about it.
I need clarification on which of these two changes is breaking or if both are. This should be included in the changelog

yes, I included the v5 default because I was going to make a breaking change Major anyway. Latest issues with the plugin involved users not setting it to 5. It makes sense to be 5 as default right now.
I don't know how to make 2 PR's without having to make 2 majors, which seemed excessive to me.

I don't know how to make 2 PR's without having to make 2 majors, which seemed excessive to me.

You can mark them both as major changes but it'll only bump the major version once if  theyre released together.

I don't know how to make 2 PR's without having to make 2 majors, which seemed excessive to me.

You can mark them both as major changes but it'll only bump the major version once if theyre released together.
But seaveit like this for this pr.

ah yeah, I forgot the system after a merged PR there will be a release PR.

Cheers mate


Handle kube-vip deployment in single-node cluster

Issue #, if available: Services can be exposed as LoadBalancer type supported by kube-vip. But in single-node cluster, kube-vip daemonset cannot be deployed correctly as it has to run in controlplane nodes. So we need this adjustment, to let the kube-vip daemonset of cp nodes to handle LoadBalancer services.
Description of changes:
Testing (if applicable):

Unit test
Manual tested SkipLoadBalancerDeployment on single-node cluster, when the field is set to false/true

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

/approve

/lgtm


Deployment is failing: image has no src or srcset attribute (line 186)

https://travis-ci.org/GabLeRoux/gableroux.github.io/builds/290024678#L819

Added data-proofer-ignore to svg tag 👍


Yarn link is broken

Hi Keven!
I realized that the current version has a problem, the yarn link isn't working... I saw the message you left in the release to do the yarn unlink but it didn't work either...
I'm leaving a suggestion here for future users and maybe even yourself if you want to tweak it somehow.
Instead of using Yarn Link, use npm link inside the repository and inside the repository you're going to use the CLI type npm link gitray.
That's it! Cheers!

@rafaelpdemelo readme changed :)
Feel free to add more suggestions and pull requests whenever necessary, your opinion is very welcome \o/


completed-docs rule doesn't shows errors

Bug Report

TSLint version: 5.2.0
TypeScript version: 2.3.2
Running TSLint via: (pick one) VSCode

TypeScript code being linted

export class MyTest {
	private _myVar: number;

	private test: string[] = [];

	constructor() {
		// TODO:
	}

	public getSomething(): number {
		console.log("Hello World");
		if (this._myVar) {
			return this._myVar;
		}

		return -1;
	}

	public doSth() {
		this.execute(p => console.log(p));
	}

	private execute(cb: (param: string) => void) {
		if (cb) {
			cb("Hallo");
		}
	}
}

with tslint.json configuration:
{
	"defaultSeverity": "error",
	"extends": [
		"tslint:recommended"
	],
	"jsRules": {},
	"rules": {
		"indent": [
			true,
			"tabs"
		],
		"eofline": true,
		"no-console": [
			true,
			"debug",
			"error",
			"info"
		],
		"variable-name": [
			true,
			"check-format",
			"allow-leading-underscore"
		],
		"array-type": [
			true,
			"array"
		],
		"arrow-parens": false,
		"class-name": true,
		"completed-docs": [
			true,
			{
				"classes": {
					"visibilities": "all"
				},
				"enums": {
					"visibilities": "all"
				},
				"functions": {
					"visibilities": "all"
				},
				"methods": {
					"privacies": "all",
					"locations": "all"
				},
				"properties": {
					"privacies": "all",
					"locations": "all"
				}
			}
		]
	},
	"rulesDirectory": []
}

or
...
		"completed-docs": [
			true,
			"classes",
			"functions",
			"methods",
			"properties"
		]
...

Actual behavior
It shows no errors or warnings about missing or incomplete documentation.
Expected behavior
It should show errors or warnings about missing or incomplete documentation.

I think this is the same as #2701, fixed by #2749

Still unable to get working on TSLint 5.5.0 with rule settings:
    "completed-docs": [
            true,
            {
                "classes":    {"visibilities": ["exported"]},
                "enums":      {"visibilities": ["exported"]},
                "functions":  {"visibilities": ["exported"]},
                "interfaces": {"visibilities": ["exported"]},
                "namespaces": {"visibilities": ["exported"]},
                "types":      {"visibilities": ["exported"]},
                "variables":  {"visibilities": ["exported"]},
                "methods":    {"locations": "all", "privacies": ["public"]},
                "properties": {"locations": "all", "privacies": ["public"]}
            }
        ],

TSlint does not complain on non-documented public methods.
But complains well on exported though.

I'm having the same issue. Running tslint -p . shows the appropriate errors but vscode does not.

This rule requires the type information. That's currently not possible with vscode-tslint. Therefore this rule is simply ignored.
You can give the experimental next version of vscode-tslint a try: https://marketplace.visualstudio.com/items?itemName=eg2.ts-tslint

@adidahiya, looks like it is not duplicate, 'cos not fixed by #2749

I run into the same issue. Tslint via CLI reports the missing documentation properly. However, PhpStorm ignores that particular error and reports nothing.

To solve this problem the rule could be refactored to no longer use the type checker.
Getting the JSDoc is fairly easy, I already did that in deprecation-rule. The tricky part is finding all merged declarations and collect all JSDoc comments from them.
/**
 * Complete documenation
 */
interface Foo {
}

// this one has no documentation, but since it's merged with the interface above, the rule should not fail on it
class Foo {
}

I'm having the same issue with IntelliJ: The CLI reports all issues, IntelliJ reports all, but documentation issues, maybe more... (Win10, JDK 1.8.0_152, IntelliJ 2017.2.5, IntelliJ tslint plugin 172.4343.14, node 6.9.4, tslint 5.7.0)

This issue could be fixed, but the behavior of the rule would differ in certain cases.
Please see #3376 and leave a comment over there so we get some feedback whether this change is accepted by the community.

any update?

PR #3557 to remove the use of the type checker from completed-docs is still in review
https://github.com/Microsoft/typescript-tslint-plugin experimentally will show typed rule failures in VS Code.

Exciting!


i can´t enter chroot

name: LeonMT1
encrypted: no
Entering /mnt/stateful_partition/crouton/chroots/LeonMT1...
/usr/local/bin/crash_reporter_wrapper: 119: exec: /var/run/crw/crw: Permission denied
WARNING: Unable to register core dump handler.
crouton: version 1-20221126232257~master:ae594340
release: focal
architecture: amd64
targets: xfce
host: version 15359.37.0 (Official Build) beta-channel coral
kernel: Linux localhost 5.10.169-21796-gb995038a188c #1 SMP PREEMPT Mon Mar 27 18:51:34 PDT 2023 x86_64 x86_64 x86_64 GNU/Linux
freon: yes
Unmounting /mnt/stateful_partition/crouton/chroots/LeonMT1...
name: xenial
encrypted: no
Entering /mnt/stateful_partition/crouton/chroots/xenial...
/usr/local/bin/crash_reporter_wrapper: 119: exec: /var/run/crw/crw: Permission denied
WARNING: Unable to register core dump handler.
crouton: version 1-20221126232257~master:ae594340
release: xenial
architecture: amd64
targets: xfce
host: version 15359.37.0 (Official Build) beta-channel coral
kernel: Linux localhost 5.10.169-21796-gb995038a188c #1 SMP PREEMPT Mon Mar 27 18:51:34 PDT 2023 x86_64 x86_64 x86_64 GNU/Linux
freon: yes
Unmounting /mnt/stateful_partition/crouton/chroots/xenial...```

#### Please describe your issue:
When i type "sudo enter-chroot" then he says: ```Entering /mnt/stateful_partition/crouton/chroots/LeonMT1...
/usr/local/bin/crash_reporter_wrapper: 119: exec: /var/run/crw/crw: Permission denied
WARNING: Unable to register core dump handler.
UID 1000 not found in LeonMT1
Unmounting /mnt/stateful_partition/crouton/chroots/LeonMT1...```

I have the same problem siince updating ChromeOs. Can you help me ?

try running sudo chmod 777 /var/run/crw/crw in the host. It will need to be ran every time the Chromebook gets restarted tho

try running sudo chmod 777 /var/run/crw/crw in the host. It will need to be ran every time the Chromebook gets restarted tho

Hello! It did not help. Writes "/usr/local/bin/crash_reporter_wrapper: 119: exec: /var/run/crw/crw: Permission denied"

It looks like your chroot never fully installed. First, remove it with
sudo rm -R /mnt/stateful_partition/crouton/chroots/*
then try again with
sudo CROUTON_BRANCH=silence crouton -r xenial -t xfce


Update wxGlade importing to better support python-settings

Description:

While wxGlade only support a small subset of the wxWidgets controls that wxFormBuilder supports, it does have significantly better support for Python code. We need to take a pass through our wxGlade importer and add more support for the Python-specific settings that wxGlade uses.

It's worth noting that there aren't a lot of wxGlade projects on github -- I found only 5 pages of *.wxg files. I've downloaded several dozen of the most current ones to provide testing. Between the low number of projects, and the limited support for wxWidgets in wxGlade itself, working on the Importing is a somewhat low priority unless someone specifically requests a better conversion.
That said, I did just submit a PR to update importing, and I plan on doing one more PR once I've added some additional debugging/testing functionality to wxUiEditor.

This still needs more work, but it's not worth holding up the 1.2 release for, so removing the milestone.


[#231] user defined service properties

Notes for Reviewer

Pre-Review Checklist for the PR Author

[x] Add sensible notes for the reviewer
[x] PR title is short, expressive and meaningful
[x] Relevant issues are linked in the References section
[x] Every source code file has a copyright header with SPDX-License-Identifier: Apache-2.0 OR MIT
[x] Branch follows the naming format (iox2-123-introduce-posix-ipc-example)
[x] Commits messages are according to this guideline

[x] Commit messages have the issue ID ([#123] Add posix ipc example)
[x] Commit author matches Eclipse Contributor Agreement (and ECA is signed)

[x] Tests follow the best practice for testing
[ ] Changelog updated in the unreleased section including API breaking changes
[x] Assign PR to reviewer
[ ] All checks have passed (except task-list-completed)

Checklist for the PR Reviewer

[ ] Commits are properly organized and messages are according to the guideline
[ ] Unit tests have been written for new behavior
[ ] Public API is documented
[ ] PR title describes the changes

Post-review Checklist for the PR Author

[ ] All open points are addressed and tracked via issues

References

Closes #231

@jasonashton I think this could be interesting for you.


Support for Ruby runtime

Is your feature request related to a problem? Please describe.
I'm building https://github.com/patterns-ai-core/langchainrb and I would like to be able to be able to integrate your tool if it's able to execute Ruby code in a sandbox environment. Do you have any plans to add the Ruby runtime?
Describe alternatives you've considered
Currently using https://github.com/ukutaht/safe_ruby but it's an extremely outdated library.

Sorry for the late response @andreibondarev.
I think adding https://github.com/SciRuby/iruby as a custom Jupyter runtime, similar to how we add Java, R, etc. here, https://github.com/e2b-dev/code-interpreter/blob/beta/template/Dockerfile#L26 should allow you to execute Ruby.
The instructions about how to create a custom template with a modified Dockerfile are here: https://e2b.dev/docs/guide/beta-migration#custom-template.


DS3 crashes on stream

When I try to stream the Dark Souls 3 window to Discord when the Archipelago mod is installed, whether it's connected to the server or not, it crashes immediately with the following window:

Hi, I also encountered this issue a long time ago and I asked Br00ty to refresh my memories.
This was related to the AP mod running along modengine and we fixed this by setting blockNetworkAccess to true in the modengine.ini.
Another way to share your game was to share the entire screen which doesn't seem to make it crash.
Please let me know if it resolved your issue

I am running it along with ModEngine, but blockNetworkAccess=1 is already set and it's still crashing. I can share my screen, but I'd much prefer to share my application window if possible.

Sorry I just tried and the param should be set to 0 as follow blockNetworkAccess=0.
I don't know what's happening here but AP mod and Discord probably try to access the same part of the "low level hook to block game from ever connecting to the internet" mentioned by modEngine.

Confirm that blockNetworkAccess=0 works.


I try to get GA stats for some pages in a loop, but after around 20 iterations I get cURL error 60: SSL certificate problem

I try to get google analytics stats for some pages in a loop, but after around 20 iterations I get "cURL error 60: SSL certificate problem". I tried with 10 iterations in loop and working. My loop is limited to 60 iterations, but seems that around iteration 20, crashes with this error:

PHP Fatal error:  Uncaught exception 'GuzzleHttp\Exception\RequestException' with message 'cURL error 60: SSL certificate problem: unable to get local issuer certificate (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)' in ...\vendor\guzzlehttp\guzzle\src\Handler\CurlFactory.php:187
Stack trace:
#0 ...\vendor\guzzlehttp\guzzle\src\Handler\CurlFactory.php(150): GuzzleHttp\Handler\CurlFactory::createRejection(Object(GuzzleHttp\Handler\EasyHandle), Array)
#1 ...\vendor\guzzlehttp\guzzle\src\Handler\CurlFactory.php(103): GuzzleHttp\Handler\CurlFactory::finishError(Object(GuzzleHttp\Handler\CurlHandler), Object(GuzzleHttp\Handler\EasyHandle), Object(GuzzleHttp\Handler\CurlFactory))
#2 ...\vendor\guzzlehttp\guzzle\src\Handler\CurlHandler.php(43): GuzzleHttp\Handler\CurlFactory::finish(Object(GuzzleHttp\Handler\CurlHandler), Object(GuzzleHttp\Handler\EasyHandle), Object(GuzzleHttp\Handler\CurlFactory))
#3 ...\vendor\guzzlehttp\guzzle\src\Handler\CurlFactory.php on line 187
Fatal error: Uncaught exception 'GuzzleHttp\Exception\RequestException' with message 'cURL error 60: SSL certificate problem: unable to get local issuer certificate (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)' in ...\vendor\guzzlehttp\guzzle\src\Handler\CurlFactory.php:187
Stack trace:
#0 ...\vendor\guzzlehttp\guzzle\src\Handler\CurlFactory.php(150): GuzzleHttp\Handler\CurlFactory::createRejection(Object(GuzzleHttp\Handler\EasyHandle), Array)
#1 ...\vendor\guzzlehttp\guzzle\src\Handler\CurlFactory.php(103): GuzzleHttp\Handler\CurlFactory::finishError(Object(GuzzleHttp\Handler\CurlHandler), Object(GuzzleHttp\Handler\EasyHandle), Object(GuzzleHttp\Handler\CurlFactory))
#2 ...\vendor\guzzlehttp\guzzle\src\Handler\CurlHandler.php(43): GuzzleHttp\Handler\CurlFactory::finish(Object(GuzzleHttp\Handler\CurlHandler), Object(GuzzleHttp\Handler\EasyHandle), Object(GuzzleHttp\Handler\CurlFactory))
#3 ...\vendor\guzzlehttp\guzzle\src\Handler\CurlFactory.php on line 187

Google Client:
$client = new Google_Client();
$client->setAuthConfig($this->clientSecretsPath);
$client->addScope(Google_Service_Analytics::ANALYTICS_READONLY);
$client->setAccessType('offline');
$client->setApprovalPrompt('force');
$client->setRedirectUri($cfg_gapi['redirect']);
$httpClient = new \GuzzleHttp\Client(array( 'curl' => array( CURLOPT_SSL_VERIFYPEER => false ), ));//CURLOPT_CAINFO => $this->cacertPath,
$client->setHttpClient($httpClient);

For $httpClient I tried and CURLOPT_CAINFO , but same result.
I try to get stats for details pages in a recipe web site: sessions, visits, uniquevisits for 2years ago, 1 year ago, 30 days ago, 7days ago, 1 day ago. I have around 50000 recipes. Seems that hard to get these stats.
Any help can be useful.
Thank You.

..PHP Fatal error:  Uncaught exception 'Google_Service_Exception' with message '{
"error": {
"code": 503,
"message": "The service is currently unavailable.",
"errors": [
{
"message": "The service is currently unavailable.",
"domain": "global",
"reason": "backendError"
}
],
"status": "UNAVAILABLE"
}
}

If you're getting backend errors, you should try to retry the service. If you're getting a certificate error, try the following:

Save the following to cacert.pem: https://curl.haxx.se/ca/cacert.pem

put it here:

C:\xampp\php\extras\ssl\cacert.pem

in your php.ini put this line in this section:
;;;;;;;;;;;;;;;;;;;;
; php.ini Options  ;
;;;;;;;;;;;;;;;;;;;;

curl.cainfo = "C:\xampp\php\extras\ssl\cacert.pem"

restart your webserver/apache


Factor out enqueue logic from Controller

Part of #213.
Just moving code around, applying boyscout rule as I go. Review should be easy :)
I couldn't write any tests because ConfigPaths won't let me override the path to the queue file. I briefly considered adding a method just for that, but then saw that it's a bigger problem. I'll write tests after #349 is fixed.

Coverage decreased (-7.0e-05%) to 39.849%

-7e-5%! That's, like, 7 lines in a 10M LOC application. Nice one, Coveralls!

Sorry, forgot to rebase onto current master, which was important to do since we finally have OS X build back.

Coverage increased (+0.08%) to 40.071% when pulling e36963ad0fef796e5eee46450894b79a5778a073 on feature/queuemanager into a08642551acd2569562e534a443176dd7d4b0acc on master.

Coverage increased (+0.08%) to 40.071% when pulling e36963ad0fef796e5eee46450894b79a5778a073 on feature/queuemanager into a08642551acd2569562e534a443176dd7d4b0acc on master.

I don't have more comment or suggestions, feel free to merge this change. :)
śr., 7.11.2018, 18:24 użytkownik Alexander Batischev <
<EMAIL_ADDRESS>napisał:

Give me a sign if you're OK with me merging this, @kmws
https://github.com/kmws. And don't be shy about blocking the PR if
you've found something worthy of a comment. ;)
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/newsboat/newsboat/pull/350#issuecomment-436706416,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ADGzlG-hE2qVWzE9pYijhk_lpWyqmtD_ks5usxdjgaJpZM4YOWvY
.


Schema Registry: bump Slick to latest version

Deprioritizing it as it looks like current versions of akka/akka-http are happy with Slick 2.

Pushing back this migration to next release.


Document 1 << 37

I'm pretty positive about this.

is there any source for this?

I've seen other discussions saying that this is what the flag is as well, further confirming my suspicions.

I have been previously disabled but only have UNKNOWN_FLAG_39, UNKNOWN_FLAG_40, UNKNOWN_FLAG_43 of unknowns

Disabled by TnS, or anti-spam?

All the accounts I tested were disabled by TnS.

Ah - I was disabled by antispam

I've had some other people confirm similar to your friends

My flags contain UNKNOWN_FLAG_37 and I have been disabled before if that helps.

Ah - I was disabled by antispam

Then it should probably be named previously_disabled_by_tns

if you could make that change that'd be great

Or even shorter: PREVIOUSLY_MANUALLY_DISABLED

manual disables can be done by non-tns
best to keep it explicit

Oh hmm, I saw someone say that the flag is being disabled for ToS violations, not explicitly by TnS.

Oh hmm, I saw someone say that the flag is being disabled for ToS violations, not explicitly by TnS.

not correct

Alright.

1<<37 was moved to an unknown because of an inconsistency and we're currently in the middle of trying to work it out. It might end up that our original assumption was correct but for now I'll leave this open.

I have flag 1 << 37 and I have never been disabled or even warned by T&S.

A bunch more data packages were sent about an hour ago.
I can confirm this. A couple accounts had it without (to my knowledge) ever being disabled.
Maybe it's a "suspicious" flag?

Personally, I have 39, 40, and 43, but not 37.

I have 39, 40, and 43, but not 37. Haven't been actioned on by tns or anti-spam ever.

#9


Updated Troubleshooting doc with yarn error

This PR updates the Troubleshooting document with a solution on how to address a yarn error.

@U8NWXD PTAL


go1.17 stack traces are problematic

What version of Go are you using (go version)?

$ go version
go version go1.17rc1 darwin/amd64

Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (go env)?
go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN="/Users/cpuguy83/go/bin"
GOCACHE="/Users/cpuguy83/Library/Caches/go-build"
GOENV="/Users/cpuguy83/Library/Application Support/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/cpuguy83/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/cpuguy83/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/Users/cpuguy83/sdk/go1.17rc1"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/Users/cpuguy83/sdk/go1.17rc1/pkg/tool/darwin_amd64"
GOVCS=""
GOVERSION="go1.17rc1"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/cpuguy83/dev/test/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/h0/019q23y92j58nhjw33nyjd1h0000gn/T/go-build429528351=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

Trying out the new stack traces in go1.17rc1.

This happens when the run happens in a goroutine. If I run this without the goroutine it gives the expected(-ish) values:

goroutine 1 [running]:
main.getStack({0x0, 0xc0000001a0}, {0xc000092f70, 0x1004b79}, 0x60, {{0x0, 0x0}}, 0x1015be5)
	/Users/cpuguy83/dev/test/stack.go:19 +0x45
 16 package main
main.main()
	/Users/cpuguy83/dev/test/stack.go:14 +0x4f

Outside of the fact that this just seems wrong, what worries me is I've often used these stack traces to track down dead locks in my code where, as an example, I can trace an argument being passed down the stack to find "Request A is blocked on a mutex, and request B is blocked on "system doing things" (maybe blocked in a syscall, an RPC request, etc...) because the argument value is consistent.
What did you expect to see?
Not 0x0 for argument values in the trace
What did you see instead?
0x0 for argument values in the trace

Duplicate of #45728

Oh, thanks!


Using Old SDK

The example shown above is using vss-web-extension-sdk with last commit in 2018. There appears to be another extension SDK now azure-devops-extension-sdk. Please see if this doc needs to be updated with the latest code.

Document Details
⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

ID: 14955ee9-29f2-46fe-3a8d-a42666f53ffc
Version Independent ID: 5d417cd0-a671-ee30-8fca-5f8b0addd328
Content: Develop a web extension for Azure DevOps Services
Content Source: docs/extend/get-started/node.md
Product: devops
Technology: devops-ecosystem
GitHub Login: @willsmythe
Microsoft Alias: wismythe

Duplicate of #3848


Support grants

Overview
Support grants as described in https://docs.getdbt.com/reference/resource-configs/grants
Tested using sql-standard access control on a Hive catalog.
Checklist

[x] I have run this code in development and it appears to resolve the stated issue
[x] This PR includes tests, or tests are not required/relevant for this PR
[x] README.md updated and added information about my change
[x] I have run changie new to create a changelog entry

Created 2 follow up issues #147, #146

@findinpath, @hovaesco : outside of the container image (that's being replaced right now). Are there any more blockers in this PR.
I would like to make a new release of dbt 1.2 today (including grants) and then focus on the 1.3 version.


Added cancelQueryTimeout to cancel QueryTimeout on Connection and Statement

Extension of PR #560.
Adds new property cancelQueryTimeout on both Connection and Statement classes. The Connection level property is used by all statements by default, while setting it at Statement level overrides the connection property.
The fix will address issue #525 where queryTimeout hangs and does not throw exception due to silent dropping of TCP connection.
The driver now reads timeout values from statement being executed and not connection (Changed from #560 initial implementation) and shall wait the total amount of cancelQueryTimeout + queryTimeout to drop the connection and close the channel.
Note: The new connection property of cancelQueryTimeout will be effective only if the queryTimeout is set in the driver.

Codecov Report

Merging #674 into dev will decrease coverage by 0.02%.
The diff coverage is 34.72%.

@@             Coverage Diff              @@
##                dev     #674      +/-   ##
============================================
- Coverage     48.16%   48.13%   -0.03%
- Complexity     2575     2581       +6
============================================
  Files           113      113
  Lines         26587    26645      +58
  Branches       4436     4449      +13
============================================
+ Hits          12805    12825      +20
- Misses        11644    11677      +33
- Partials       2138     2143       +5

Flag
Coverage Δ
Complexity Δ

#JDBC42
48.01% <34.72%> (-0.04%)
2576 <2> (+6)

#JDBC43
48.02% <34.72%> (-0.08%)
2575 <2> (+2)

Impacted Files
Coverage Δ
Complexity Δ

...om/microsoft/sqlserver/jdbc/SQLServerResource.java
100% <ø> (ø)
4 <0> (ø)
:arrow_down:

.../microsoft/sqlserver/jdbc/SQLServerDataSource.java
45.19% <0%> (-0.48%)
66 <0> (ø)

...oft/sqlserver/jdbc/SQLServerPreparedStatement.java
50.85% <100%> (ø)
157 <0> (ø)
:arrow_down:

.../com/microsoft/sqlserver/jdbc/SQLServerDriver.java
76.98% <100%> (+0.12%)
25 <0> (ø)
:arrow_down:

...om/microsoft/sqlserver/jdbc/SQLServerBulkCopy.java
52.67% <100%> (ø)
241 <0> (+1)
:arrow_up:

.../microsoft/sqlserver/jdbc/SQLServerConnection.java
45.67% <20%> (-0.16%)
288 <1> (+1)

...m/microsoft/sqlserver/jdbc/SQLServerStatement.java
58.84% <25%> (-0.77%)
133 <1> (+1)

...in/java/com/microsoft/sqlserver/jdbc/IOBuffer.java
54.68% <41.66%> (-0.15%)
0 <0> (ø)

...m/microsoft/sqlserver/jdbc/SQLServerResultSet.java
33.14% <50%> (+0.27%)
245 <0> (+2)
:arrow_up:

...ncurrentlinkedhashmap/ConcurrentLinkedHashMap.java
38.54% <0%> (-0.65%)
42% <0%> (-1%)

... and 5 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 2982983...81348c1. Read the comment docs.

Hi @ulvii - made recommended fixes. Please review once more.
Thanks!


ci(bright-cli): upgrade github artifact actions to v4

Update the GitHub Action upload-artifact from version 3 to version 4. The upgrade provides enhanced artifact handling, and compatibility with the latest GitHub Actions runtime features.

This won’t work with the current setup: https://github.com/NeuraLegion/bright-cli/pull/614#issuecomment-2478550789

@bramkor please ensure that all future PRs are opened against the next branch

@derevnjuk @orubin note taken, thanks.
Or I asked in our group if I should open against master or next, and was told to open against master. Let's make sure we are all aligned.

Thanks @derevnjuk
I guess you meant git merge --no-ff master one line before the last.
Right?

@orubin yes, thanks 👍🏾

@orubin workflow is still failing (e.g. https://github.com/NeuraLegion/bright-cli/actions/runs/12128761278/job/33815969270). After migrating to ubi8, you should replace yum with microdnf.

@orubin workflow is still failing (e.g. https://github.com/NeuraLegion/bright-cli/actions/runs/12128761278/job/33815969270). After migrating to ubi8, you should replace yum with microdnf.

Thanks @derevnjuk - noted and appreciated.


Typo in mdc-103-kotlin

This is the third of 4 codelabs that will guide you through building an app called Shrine, an e-commerce website that sells clothing and home goods.The related codelabs can be found at:MDC-101: Material Components (MDC) BasicsMDC-102: Material Design Structure and LayoutMDC-104: Material Design Advanced ComponentsBy the end of MDC 104, you'll build a website that looks like this:

We're building an app, not a website. Typo I assume?

Thanks for filing this issue. We fixed the typo.


[T4A2][W14-B2] Rachel Yang

Ready for review

@JJ-Rachel Since you converted the parse method of Parser to a class-level method, you would like to convert your Main class to be using it as a class method. See Zhi Yong's


fix: revert cors proxy, instead use fonts from the Design Library site

:tada: This PR is included in version 4.0.2 :tada:
The release is available on:

npm package (@latest dist-tag)
GitHub release

Your semantic-release bot :package::rocket:


How to generate Log file in XML/HTML format?

How to generate Log file in XML/HTML format?
So, we can open it in browser.

I believe you would need to create your own Formatter.
While my search wasn't exhaustive, I did look around for one that exists, but didn't find any.


Update certificate fingerprint

Per this issue https://github.com/aws-actions/configure-aws-credentials/issues/357, the fingerprint has changed.
FYI We also publish a module that dynamically fetches the cert value that may be more future proof: https://github.com/voquis/terraform-aws-github-actions-oidc-role

Thanks, @danial-k!
Resolved in https://github.com/hectcastro/terraform-aws-github-actions-oidc/pull/3.


Clarification on Encryption Algorithms and Apple's Compliance Requirements

Hello WalletConnect Team,
I hope this message finds you well. I'm currently in the process of submitting my app to the Apple App Store, and I've encountered a question regarding the encryption algorithms used by the services and libraries integrated into the app. Specifically, Apple is inquiring about the type of encryption algorithms implemented, and whether they are proprietary, standard, or both.
Since my app utilizes WalletConnect 2.0 for data transmission, I wanted to reach out and seek clarification. Based on my understanding and research, it seems that WalletConnect might employ both standard encryption algorithms and its own protocols. Can you confirm if this is accurate?
Furthermore, given that I'm using WalletConnect, would I need to complete all the associated paperwork and compliance documentation for Apple based on the encryption methods WalletConnect employs?
Your guidance on this matter would be greatly appreciated, as it will help streamline the app submission process and ensure compliance with Apple's requirements.
Thank you for your time and assistance.
Warm regards,
ramvi

We only use Apple's implementation(CryptoKit) of ChaCha20-Poly1305.
I hope this helps.

@llbartekll,
Thank you so much for your response and for clarifying the encryption methods used by WalletConnect. Your information about the encryption used is very helpful.
To confirm my understanding and proceed with the app submission process, does this mean the answer is "No" to the "Export Compliance Information" question within Apple's requirements?
I appreciate your time and help with this.
Warm regards,
ramvi

I am sorry but I am not a legal advisor :D
but "no" always worked for me :)

I understand that you're not a legal advisor, and I truly appreciate your responses to my questions. They have been extremely helpful in clarifying the situation.
Considering that every app that integrates WalletConnect will likely face these same questions when submitting to the Apple App Store, I believe that incorporating this information into the official documentation could benefit other developers as well.
Would you like me to create a pull request (PR) to add this information to the documentation?
Thank you once again for your assistance.
Warm regards,
ramvi


Adds technology logos to the README

As shown in this PR, logos for the various languages used have been added to the README. Anyone can click the logos and simply view the languages that were used for this project.

Atleast do some valid quality contribution