/* Copyright (C) 2017-2024 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, José Rebelo, Lukas Veneziano, Maxim Baz
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see . */
package nodomain.freeyourgadget.gadgetbridge.util;
import android.content.Context;
import android.content.pm.LauncherActivityInfo;
import android.content.pm.LauncherApps;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.os.UserHandle;
import android.os.UserManager;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
public class NotificationUtils {
private static final Logger LOG = LoggerFactory.getLogger(NotificationUtils.class);
@NonNull
public static String getPreferredTextFor(NotificationSpec notificationSpec, int lengthBody, int lengthSubject, Context context) {
switch (notificationSpec.type) {
case GENERIC_ALARM_CLOCK:
return StringUtils.getFirstOf(notificationSpec.title, notificationSpec.subject);
case GENERIC_SMS:
case GENERIC_EMAIL:
return formatText(notificationSpec.sender, notificationSpec.subject, notificationSpec.body, lengthBody, lengthSubject, context);
case GENERIC_NAVIGATION:
return StringUtils.getFirstOf(notificationSpec.title, notificationSpec.body);
case CONVERSATIONS:
case FACEBOOK_MESSENGER:
case GOOGLE_MESSENGER:
case GOOGLE_HANGOUTS:
case HIPCHAT:
case KAKAO_TALK:
case LINE:
case RIOT:
case SIGNAL:
case WIRE:
case SKYPE:
case SNAPCHAT:
case TELEGRAM:
case THREEMA:
case KONTALK:
case ANTOX:
case TWITTER:
case WHATSAPP:
case VIBER:
case WECHAT:
return StringUtils.ensureNotNull(notificationSpec.body);
}
return "";
}
@NonNull
public static String formatSender(String sender, Context context) {
if (sender == null || sender.length() == 0) {
return "";
}
return context.getString(R.string.StringUtils_sender, sender);
}
@NonNull
public static String formatText(String sender, String subject, String body, int lengthBody, int lengthSubject, Context context) {
String fBody = StringUtils.truncate(body, lengthBody);
String fSubject = StringUtils.truncate(subject, lengthSubject);
String fSender = formatSender(sender, context);
StringBuilder builder = StringUtils.join(" ", fBody, fSubject, fSender);
return builder.toString().trim();
}
public static String getPreferredTextFor(CallSpec callSpec) {
return StringUtils.getFirstOf(callSpec.name, callSpec.number);
}
@Nullable
public static Drawable getAppIcon(final Context context, final String packageName) {
try {
return context.getPackageManager().getApplicationIcon(packageName);
} catch (final PackageManager.NameNotFoundException ignored) {
LOG.warn("Failed to find icon for {}, attempting fallback", packageName);
return getAppIconFallback(context, packageName);
}
}
/**
* Fallback method to get an app icon - iterate through all the users and attempt to find the
* app. This includes work profiles.
*/
@Nullable
private static Drawable getAppIconFallback(final Context context, final String packageName) {
try {
final LauncherApps launcherAppsService = (LauncherApps) context.getSystemService(Context.LAUNCHER_APPS_SERVICE);
final UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
final List userProfiles = userManager.getUserProfiles();
// Skip user 0 (current, main user)
for (int i = 1; i < userProfiles.size(); i++) {
final UserHandle userHandle = userProfiles.get(i);
final List activityList = launcherAppsService.getActivityList(packageName, userHandle);
if (!activityList.isEmpty()) {
LOG.info("Found {} icons for {} in user {}", activityList.size(), packageName, userHandle);
return activityList.get(0).getIcon(0);
}
}
LOG.warn("Failed to find fallback icon for {}", packageName);
} catch (final Exception e) {
LOG.error("Error during fallback icon search", e);
}
return null;
}
}