-
-
Notifications
You must be signed in to change notification settings - Fork 11k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use reflection to create AudioRecord
- Loading branch information
Showing
6 changed files
with
657 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<issues format="6" by="lint 7.4.0" type="baseline" client="gradle" dependencies="false" name="AGP (7.4.0)" variant="fatal" version="7.4.0"> | ||
|
||
<issue | ||
id="BlockedPrivateApi" | ||
message="Reflective access to withPackageName is forbidden when targeting API 33 and above" | ||
errorLine1=" Method withPackageNameMethod = AttributionSource.class.getDeclaredMethod("withPackageName"," | ||
errorLine2=" ^"> | ||
<location | ||
file="src/main/java/com/genymobile/scrcpy/wrappers/AudioRecordWrapper.java" | ||
line="231" | ||
column="52"/> | ||
</issue> | ||
|
||
<issue | ||
id="BlockedPrivateApi" | ||
message="Reflective access to asScopedParcelState is forbidden when targeting API 33 and above" | ||
errorLine1=" Method asScopedParcelStateMethod = AttributionSource.class.getDeclaredMethod("asScopedParcelState");" | ||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> | ||
<location | ||
file="src/main/java/com/genymobile/scrcpy/wrappers/AudioRecordWrapper.java" | ||
line="240" | ||
column="52"/> | ||
</issue> | ||
|
||
<issue | ||
id="BlockedPrivateApi" | ||
message="Reflective access to mPrivacySensitive is forbidden when targeting API 33 and above" | ||
errorLine1=" Field mPrivacySensitiveField = AudioRecord.Builder.class.getDeclaredField("mPrivacySensitive");" | ||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> | ||
<location | ||
file="src/main/java/com/genymobile/scrcpy/wrappers/AudioRecordWrapper.java" | ||
line="326" | ||
column="44"/> | ||
</issue> | ||
|
||
<issue | ||
id="BlockedPrivateApi" | ||
message="Reflective access to mContext is forbidden when targeting API 33 and above" | ||
errorLine1=" Field mContextField = AudioRecord.Builder.class.getDeclaredField("mContext");" | ||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> | ||
<location | ||
file="src/main/java/com/genymobile/scrcpy/wrappers/AudioRecordWrapper.java" | ||
line="364" | ||
column="39"/> | ||
</issue> | ||
|
||
</issues> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
135 changes: 135 additions & 0 deletions
135
server/src/main/java/com/genymobile/scrcpy/wrappers/AudioAttributesWrapper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
package com.genymobile.scrcpy.wrappers; | ||
|
||
import com.genymobile.scrcpy.Ln; | ||
|
||
import android.media.AudioAttributes; | ||
|
||
import java.lang.reflect.InvocationTargetException; | ||
import java.lang.reflect.Method; | ||
import java.util.Set; | ||
|
||
public class AudioAttributesWrapper { | ||
private static Method getCapturePresetMethod; | ||
private static Method setCapturePresetMethod; | ||
private static Method getTagsMethod; | ||
|
||
private static Method getGetCapturePresetMethod() throws NoSuchMethodException { | ||
if (getCapturePresetMethod == null) { | ||
getCapturePresetMethod = AudioAttributes.class.getMethod("getCapturePreset"); | ||
} | ||
return getCapturePresetMethod; | ||
} | ||
|
||
public static int getCapturePreset(AudioAttributes audioAttributes) | ||
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException { | ||
try { | ||
return (int) getGetCapturePresetMethod().invoke(audioAttributes); | ||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | ||
| NoSuchMethodException e) { | ||
Ln.e("Failed to invoke AudioAttributes.getCapturePreset()", e); | ||
throw e; | ||
} | ||
} | ||
|
||
private static Method getSetCapturePresetMethod() throws NoSuchMethodException { | ||
if (setCapturePresetMethod == null) { | ||
setCapturePresetMethod = AudioAttributes.class.getMethod("setCapturePreset", int.class); | ||
} | ||
return setCapturePresetMethod; | ||
} | ||
|
||
public static void setCapturePreset(AudioAttributes audioAttributes, int preset) | ||
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException { | ||
try { | ||
getSetCapturePresetMethod().invoke(audioAttributes, preset); | ||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | ||
| NoSuchMethodException e) { | ||
Ln.e("Failed to invoke AudioAttributes.setCapturePreset()", e); | ||
throw e; | ||
} | ||
} | ||
|
||
private static Method getGetTagsMethod() throws NoSuchMethodException { | ||
if (getTagsMethod == null) { | ||
getTagsMethod = AudioAttributes.class.getMethod("getTags"); | ||
} | ||
return getTagsMethod; | ||
} | ||
|
||
@SuppressWarnings("unchecked") | ||
public static Set<String> getTags(AudioAttributes audioAttributes) | ||
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException { | ||
try { | ||
return (Set<String>) getGetTagsMethod().invoke(audioAttributes); | ||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | ||
| NoSuchMethodException e) { | ||
Ln.e("Failed to invoke AudioAttributes.getTags()", e); | ||
throw e; | ||
} | ||
} | ||
|
||
public static class Builder { | ||
private static Method setInternalCapturePresetMethod; | ||
private static Method setPrivacySensitiveMethod; | ||
private static Method addTagMethod; | ||
|
||
private static Method getSetInternalCapturePresetMethod() throws NoSuchMethodException { | ||
if (setInternalCapturePresetMethod == null) { | ||
setInternalCapturePresetMethod = AudioAttributes.Builder.class.getMethod("setInternalCapturePreset", | ||
int.class); | ||
} | ||
return setInternalCapturePresetMethod; | ||
} | ||
|
||
public static void setInternalCapturePreset(AudioAttributes.Builder builder, int preset) | ||
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, | ||
NoSuchMethodException { | ||
try { | ||
getSetInternalCapturePresetMethod().invoke(builder, preset); | ||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | ||
| NoSuchMethodException e) { | ||
Ln.e("Failed to invoke AudioAttributes.Builder.setInternalCapturePreset()", e); | ||
throw e; | ||
} | ||
} | ||
|
||
private static Method getSetPrivacySensitiveMethod() throws NoSuchMethodException { | ||
if (setPrivacySensitiveMethod == null) { | ||
setPrivacySensitiveMethod = AudioAttributes.Builder.class.getMethod("setPrivacySensitive", | ||
boolean.class); | ||
} | ||
return setPrivacySensitiveMethod; | ||
} | ||
|
||
public static void setPrivacySensitive(AudioAttributes.Builder builder, boolean privacySensitive) | ||
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, | ||
NoSuchMethodException { | ||
try { | ||
getSetPrivacySensitiveMethod().invoke(builder, privacySensitive); | ||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | ||
| NoSuchMethodException e) { | ||
Ln.e("Failed to invoke AudioAttributes.Builder.setPrivacySensitive()", e); | ||
throw e; | ||
} | ||
} | ||
|
||
private static Method getAddTagMethod() throws NoSuchMethodException { | ||
if (addTagMethod == null) { | ||
addTagMethod = AudioAttributes.Builder.class.getMethod("addTag", String.class); | ||
} | ||
return addTagMethod; | ||
} | ||
|
||
public static void addTag(AudioAttributes.Builder builder, String tag) | ||
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, | ||
NoSuchMethodException { | ||
try { | ||
getAddTagMethod().invoke(builder, tag); | ||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | ||
| NoSuchMethodException e) { | ||
Ln.e("Failed to invoke AudioAttributes.Builder.addTag()", e); | ||
throw e; | ||
} | ||
} | ||
} | ||
} |
78 changes: 78 additions & 0 deletions
78
server/src/main/java/com/genymobile/scrcpy/wrappers/AudioFormatWrapper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package com.genymobile.scrcpy.wrappers; | ||
|
||
import java.lang.reflect.InvocationTargetException; | ||
import java.lang.reflect.Method; | ||
|
||
import com.genymobile.scrcpy.Ln; | ||
|
||
import android.media.AudioFormat; | ||
|
||
public class AudioFormatWrapper { | ||
public final static int AUDIO_FORMAT_HAS_PROPERTY_NONE = 0x0; | ||
public final static int AUDIO_FORMAT_HAS_PROPERTY_ENCODING = 0x1 << 0; | ||
public final static int AUDIO_FORMAT_HAS_PROPERTY_SAMPLE_RATE = 0x1 << 1; | ||
public final static int AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_MASK = 0x1 << 2; | ||
public final static int AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_INDEX_MASK = 0x1 << 3; | ||
|
||
private static Method getPropertySetMaskMethod; | ||
private static Method channelCountFromInChannelMaskMethod; | ||
private static Method getBytesPerSampleMethod; | ||
|
||
private static Method getGetPropertySetMaskMethod() throws NoSuchMethodException { | ||
if (getPropertySetMaskMethod == null) { | ||
getPropertySetMaskMethod = AudioFormat.class.getMethod("getPropertySetMask"); | ||
} | ||
return getPropertySetMaskMethod; | ||
} | ||
|
||
public static int getPropertySetMask(AudioFormat audioFormat) | ||
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, | ||
NoSuchMethodException { | ||
try { | ||
return (int) getGetPropertySetMaskMethod().invoke(audioFormat); | ||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | ||
| NoSuchMethodException e) { | ||
Ln.e("Failed to invoke AudioFormat.getPropertySetMask()", e); | ||
throw e; | ||
} | ||
} | ||
|
||
private static Method getChannelCountFromInChannelMaskMethod() throws NoSuchMethodException { | ||
if (channelCountFromInChannelMaskMethod == null) { | ||
channelCountFromInChannelMaskMethod = AudioFormat.class.getMethod("channelCountFromInChannelMask", | ||
int.class); | ||
} | ||
return channelCountFromInChannelMaskMethod; | ||
} | ||
|
||
public static int channelCountFromInChannelMask(int channelMask) | ||
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, | ||
NoSuchMethodException { | ||
try { | ||
return (int) getChannelCountFromInChannelMaskMethod().invoke(null, channelMask); | ||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | ||
| NoSuchMethodException e) { | ||
Ln.e("Failed to invoke AudioFormat.channelCountFromInChannelMask()", e); | ||
throw e; | ||
} | ||
} | ||
|
||
private static Method getGetBytesPerSampleMethod() throws NoSuchMethodException { | ||
if (getBytesPerSampleMethod == null) { | ||
getBytesPerSampleMethod = AudioFormat.class.getMethod("getBytesPerSample", int.class); | ||
} | ||
return getBytesPerSampleMethod; | ||
} | ||
|
||
public static int getBytesPerSample(AudioFormat format, int encoding) | ||
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, | ||
NoSuchMethodException { | ||
try { | ||
return (int) getGetBytesPerSampleMethod().invoke(format, encoding); | ||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | ||
| NoSuchMethodException e) { | ||
Ln.e("Failed to invoke AudioFormat.getBytesPerSample()", e); | ||
throw e; | ||
} | ||
} | ||
} |
Oops, something went wrong.