Search in sources :

Example 71 with RequiresApi

use of androidx.annotation.RequiresApi in project xabber-android by redsolution.

the class CustomNotifSettingsFragment method getSoundTitle.

@RequiresApi(api = Build.VERSION_CODES.O)
private String getSoundTitle(NotificationChannel channel) {
    if (channel == null)
        return null;
    Uri uri = channel.getSound();
    Ringtone ringtone = RingtoneManager.getRingtone(getActivity(), uri);
    if (ringtone != null)
        return ringtone.getTitle(getActivity());
    else
        return "Unknown ringtone";
}
Also used : Ringtone(android.media.Ringtone) Uri(android.net.Uri) RequiresApi(androidx.annotation.RequiresApi)

Example 72 with RequiresApi

use of androidx.annotation.RequiresApi in project Signal-Android by WhisperSystems.

the class AudioWaveForm method generateWaveForm.

/**
 * Based on decode sample from:
 * <p>
 * https://android.googlesource.com/platform/cts/+/jb-mr2-release/tests/tests/media/src/android/media/cts/DecoderTest.java
 */
@WorkerThread
@RequiresApi(api = 23)
@NonNull
private AudioFileInfo generateWaveForm(@NonNull Uri uri) throws IOException {
    try (MediaInput dataSource = DecryptableUriMediaInput.createForUri(context, uri)) {
        long[] wave = new long[BAR_COUNT];
        int[] waveSamples = new int[BAR_COUNT];
        MediaExtractor extractor = dataSource.createExtractor();
        if (extractor.getTrackCount() == 0) {
            throw new IOException("No audio track");
        }
        MediaFormat format = extractor.getTrackFormat(0);
        if (!format.containsKey(MediaFormat.KEY_DURATION)) {
            throw new IOException("Unknown duration");
        }
        long totalDurationUs = format.getLong(MediaFormat.KEY_DURATION);
        String mime = format.getString(MediaFormat.KEY_MIME);
        if (!mime.startsWith("audio/")) {
            throw new IOException("Mime not audio");
        }
        MediaCodec codec = MediaCodec.createDecoderByType(mime);
        if (totalDurationUs == 0) {
            throw new IOException("Zero duration");
        }
        codec.configure(format, null, null, 0);
        codec.start();
        ByteBuffer[] codecInputBuffers = codec.getInputBuffers();
        ByteBuffer[] codecOutputBuffers = codec.getOutputBuffers();
        extractor.selectTrack(0);
        long kTimeOutUs = 5000;
        MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
        boolean sawInputEOS = false;
        boolean sawOutputEOS = false;
        int noOutputCounter = 0;
        while (!sawOutputEOS && noOutputCounter < 50) {
            noOutputCounter++;
            if (!sawInputEOS) {
                int inputBufIndex = codec.dequeueInputBuffer(kTimeOutUs);
                if (inputBufIndex >= 0) {
                    ByteBuffer dstBuf = codecInputBuffers[inputBufIndex];
                    int sampleSize = extractor.readSampleData(dstBuf, 0);
                    long presentationTimeUs = 0;
                    if (sampleSize < 0) {
                        sawInputEOS = true;
                        sampleSize = 0;
                    } else {
                        presentationTimeUs = extractor.getSampleTime();
                    }
                    codec.queueInputBuffer(inputBufIndex, 0, sampleSize, presentationTimeUs, sawInputEOS ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0);
                    if (!sawInputEOS) {
                        int barSampleIndex = (int) (SAMPLES_PER_BAR * (wave.length * extractor.getSampleTime()) / totalDurationUs);
                        sawInputEOS = !extractor.advance();
                        int nextBarSampleIndex = (int) (SAMPLES_PER_BAR * (wave.length * extractor.getSampleTime()) / totalDurationUs);
                        while (!sawInputEOS && nextBarSampleIndex == barSampleIndex) {
                            sawInputEOS = !extractor.advance();
                            if (!sawInputEOS) {
                                nextBarSampleIndex = (int) (SAMPLES_PER_BAR * (wave.length * extractor.getSampleTime()) / totalDurationUs);
                            }
                        }
                    }
                }
            }
            int outputBufferIndex;
            do {
                outputBufferIndex = codec.dequeueOutputBuffer(info, kTimeOutUs);
                if (outputBufferIndex >= 0) {
                    if (info.size > 0) {
                        noOutputCounter = 0;
                    }
                    ByteBuffer buf = codecOutputBuffers[outputBufferIndex];
                    int barIndex = (int) ((wave.length * info.presentationTimeUs) / totalDurationUs);
                    long total = 0;
                    for (int i = 0; i < info.size; i += 2 * 4) {
                        short aShort = buf.getShort(i);
                        total += Math.abs(aShort);
                    }
                    if (barIndex >= 0 && barIndex < wave.length) {
                        wave[barIndex] += total;
                        waveSamples[barIndex] += info.size / 2;
                    }
                    codec.releaseOutputBuffer(outputBufferIndex, false);
                    if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
                        sawOutputEOS = true;
                    }
                } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
                    codecOutputBuffers = codec.getOutputBuffers();
                } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
                    Log.d(TAG, "output format has changed to " + codec.getOutputFormat());
                }
            } while (outputBufferIndex >= 0);
        }
        codec.stop();
        codec.release();
        extractor.release();
        float[] floats = new float[BAR_COUNT];
        byte[] bytes = new byte[BAR_COUNT];
        float max = 0;
        for (int i = 0; i < BAR_COUNT; i++) {
            if (waveSamples[i] == 0)
                continue;
            floats[i] = wave[i] / (float) waveSamples[i];
            if (floats[i] > max) {
                max = floats[i];
            }
        }
        for (int i = 0; i < BAR_COUNT; i++) {
            float normalized = floats[i] / max;
            bytes[i] = (byte) (255 * normalized);
        }
        return new AudioFileInfo(totalDurationUs, bytes);
    }
}
Also used : MediaFormat(android.media.MediaFormat) IOException(java.io.IOException) ByteString(com.google.protobuf.ByteString) MediaExtractor(android.media.MediaExtractor) ByteBuffer(java.nio.ByteBuffer) MediaCodec(android.media.MediaCodec) DecryptableUriMediaInput(org.thoughtcrime.securesms.media.DecryptableUriMediaInput) MediaInput(org.thoughtcrime.securesms.media.MediaInput) WorkerThread(androidx.annotation.WorkerThread) NonNull(androidx.annotation.NonNull) RequiresApi(androidx.annotation.RequiresApi)

Example 73 with RequiresApi

use of androidx.annotation.RequiresApi in project Signal-Android by WhisperSystems.

the class JobSchedulerScheduler method schedule.

@RequiresApi(26)
@Override
public void schedule(long delay, @NonNull List<Constraint> constraints) {
    SignalExecutors.BOUNDED.execute(() -> {
        JobScheduler jobScheduler = application.getSystemService(JobScheduler.class);
        String constraintNames = constraints.isEmpty() ? "" : Stream.of(constraints).map(Constraint::getJobSchedulerKeyPart).withoutNulls().sorted().collect(Collectors.joining("-"));
        int jobId = constraintNames.hashCode();
        if (jobScheduler.getPendingJob(jobId) != null) {
            return;
        }
        Log.i(TAG, String.format(Locale.US, "JobScheduler enqueue of %s (%d)", constraintNames, jobId));
        JobInfo.Builder jobInfoBuilder = new JobInfo.Builder(jobId, new ComponentName(application, SystemService.class)).setMinimumLatency(delay).setPersisted(true);
        for (Constraint constraint : constraints) {
            constraint.applyToJobInfo(jobInfoBuilder);
        }
        jobScheduler.schedule(jobInfoBuilder.build());
    });
}
Also used : JobScheduler(android.app.job.JobScheduler) JobInfo(android.app.job.JobInfo) ComponentName(android.content.ComponentName) RequiresApi(androidx.annotation.RequiresApi)

Example 74 with RequiresApi

use of androidx.annotation.RequiresApi in project Signal-Android by WhisperSystems.

the class CameraXUtil method shouldCropImage.

@RequiresApi(21)
private static boolean shouldCropImage(@NonNull ImageProxy image) {
    Size sourceSize = new Size(image.getWidth(), image.getHeight());
    Size targetSize = new Size(image.getCropRect().width(), image.getCropRect().height());
    return !targetSize.equals(sourceSize);
}
Also used : Size(android.util.Size) RequiresApi(androidx.annotation.RequiresApi)

Example 75 with RequiresApi

use of androidx.annotation.RequiresApi in project Signal-Android by WhisperSystems.

the class CameraXUtil method getLowestSupportedHardwareLevel.

@RequiresApi(21)
public static int getLowestSupportedHardwareLevel(@NonNull Context context) {
    @SuppressLint("RestrictedApi") CameraManager cameraManager = CameraManagerCompat.from(context).unwrap();
    try {
        int supported = maxHardwareLevel();
        for (String cameraId : cameraManager.getCameraIdList()) {
            CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId);
            Integer hwLevel = characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
            if (hwLevel == null || hwLevel == CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) {
                return CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY;
            }
            supported = smallerHardwareLevel(supported, hwLevel);
        }
        return supported;
    } catch (CameraAccessException e) {
        Log.w(TAG, "Failed to enumerate cameras", e);
        return CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY;
    }
}
Also used : CameraAccessException(android.hardware.camera2.CameraAccessException) CameraCharacteristics(android.hardware.camera2.CameraCharacteristics) SuppressLint(android.annotation.SuppressLint) CameraManager(android.hardware.camera2.CameraManager) SuppressLint(android.annotation.SuppressLint) RequiresApi(androidx.annotation.RequiresApi)

Aggregations

RequiresApi (androidx.annotation.RequiresApi)117 NotificationChannel (android.app.NotificationChannel)16 Intent (android.content.Intent)13 SuppressLint (android.annotation.SuppressLint)10 NotificationManager (android.app.NotificationManager)9 Uri (android.net.Uri)9 StatusBarNotification (android.service.notification.StatusBarNotification)9 NonNull (androidx.annotation.NonNull)9 IOException (java.io.IOException)8 Notification (android.app.Notification)6 PendingIntent (android.app.PendingIntent)6 Context (android.content.Context)6 ObjectAnimator (android.animation.ObjectAnimator)5 Bundle (android.os.Bundle)5 ByteBuffer (java.nio.ByteBuffer)5 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)5 SecretKey (javax.crypto.SecretKey)5 GestureDescription (android.accessibilityservice.GestureDescription)4 TaskStackBuilder (android.app.TaskStackBuilder)4 Bitmap (android.graphics.Bitmap)4