Files
packages_apps_Settings/src/com/android/settings/media/AppVolumeSlice.java
cjybyjk c7a35a8bc1 Settings: support per-app volume [3/3]
Change-Id: I3e72a4b0fda68a5cd1e9a35fc161a1d7ddae6d7e

Signed-off-by: AnierinB <anierin@evolution-x.org>
Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>
2025-12-10 00:41:25 +09:00

151 lines
5.3 KiB
Java

/*
* Copyright (C) 2022 Project Kaleidoscope
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.media;
import static android.app.slice.Slice.EXTRA_RANGE_VALUE;
import static android.text.Spanned.SPAN_EXCLUSIVE_EXCLUSIVE;
import static com.android.settings.slices.CustomSliceRegistry.APP_VOLUME_SLICE_URI;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.media.AudioManager;
import android.media.AppVolume;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
import androidx.core.graphics.drawable.IconCompat;
import androidx.slice.Slice;
import androidx.slice.builders.ListBuilder;
import androidx.slice.builders.ListBuilder.InputRangeBuilder;
import androidx.slice.builders.SliceAction;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.slices.CustomSliceable;
import com.android.settings.slices.SliceBroadcastReceiver;
import java.util.ArrayList;
import java.util.List;
public class AppVolumeSlice implements CustomSliceable {
private static final String TAG = "AppVolumeSlice";
private static final String PACKAGE_NAME = "package_name";
private static final String ACTION_LAUNCH_DIALOG = "action_launch_dialog";
private final Context mContext;
private final AudioManager mAudioManager;
public AppVolumeSlice(Context context) {
mContext = context;
mAudioManager = context.getSystemService(AudioManager.class);
}
@Override
public void onNotifyChange(Intent intent) {
final int newPosition = intent.getIntExtra(EXTRA_RANGE_VALUE, -1);
final String packageName = intent.getStringExtra(PACKAGE_NAME);
if (!TextUtils.isEmpty(packageName)) {
mAudioManager.setAppVolume(packageName, newPosition / 100.0f);
return;
}
}
@Override
public Slice getSlice() {
final ListBuilder listBuilder = new ListBuilder(mContext, getUri(), ListBuilder.INFINITY)
.setAccentColor(COLOR_NOT_TINTED);
// Only displaying active tracks
final List<AppVolume> appVols = new ArrayList<>();
for (AppVolume vol : mAudioManager.listAppVolumes()) {
if (vol.isActive()) {
appVols.add(vol);
}
}
if (appVols.isEmpty()) {
Log.d(TAG, "No active tracks");
return listBuilder.build();
}
for (AppVolume vol : appVols) {
final CharSequence appName = Utils.getApplicationLabel(
mContext, vol.getPackageName());
IconCompat icon = getApplicationIcon(vol.getPackageName());
final SliceAction primarySliceAction = SliceAction.create(
getBroadcastIntent(mContext), icon, ListBuilder.ICON_IMAGE, appName);
listBuilder.addInputRange(new InputRangeBuilder()
.setTitleItem(icon, ListBuilder.ICON_IMAGE)
.setTitle(appName)
.setInputAction(getSliderInputAction(vol.getPackageName()))
.setMax(100)
.setValue((int)(vol.getVolume() * 100))
.setPrimaryAction(primarySliceAction));
}
return listBuilder.build();
}
private IconCompat getApplicationIcon(String packageName) {
PackageManager pm = mContext.getPackageManager();
try {
ApplicationInfo ai = pm.getApplicationInfo(packageName, 0);
Resources resources = pm.getResourcesForApplication(ai);
IconCompat icon = IconCompat.createWithResource(resources, packageName, ai.icon);
return icon;
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "Failed to get icon of " + packageName, e);
}
final Bitmap bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
return IconCompat.createWithBitmap(bitmap);
}
private PendingIntent getSliderInputAction(String packageName) {
final int requestCode = packageName.hashCode();
final Intent intent = new Intent(getUri().toString())
.setData(getUri())
.putExtra(PACKAGE_NAME, packageName)
.setClass(mContext, SliceBroadcastReceiver.class);
return PendingIntent.getBroadcast(mContext, requestCode, intent,
PendingIntent.FLAG_MUTABLE);
}
@Override
public Uri getUri() {
return APP_VOLUME_SLICE_URI;
}
@Override
public Intent getIntent() {
return null;
}
@Override
public int getSliceHighlightMenuRes() {
return R.string.menu_key_sound;
}
}