Add missed call notifications
Co-authored-by: Daniel Gultsch <daniel@gultsch.de>
This commit is contained in:
parent
e2612709af
commit
a6b88ba9e9
344
art/ic_missed_call_notification.svg
Normal file
344
art/ic_missed_call_notification.svg
Normal file
|
@ -0,0 +1,344 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="512"
|
||||||
|
height="512"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.92.3 (2405546, 2018-03-11)"
|
||||||
|
sodipodi:docname="ic_missed_call_notification.svg"
|
||||||
|
inkscape:export-filename="/home/diesys/diesys/grafica/conversation/conversation_bubble.png"
|
||||||
|
inkscape:export-xdpi="100"
|
||||||
|
inkscape:export-ydpi="100">
|
||||||
|
<defs
|
||||||
|
id="defs4">
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient3874">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#00a000;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop3876" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#00a000;stop-opacity:0;"
|
||||||
|
offset="1"
|
||||||
|
id="stop3878" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient3913">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffffff;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop3915" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffffff;stop-opacity:0;"
|
||||||
|
offset="1"
|
||||||
|
id="stop3917" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient3818">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#669900;stop-opacity:1"
|
||||||
|
offset="0"
|
||||||
|
id="stop3820" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#99cc00;stop-opacity:1"
|
||||||
|
offset="1"
|
||||||
|
id="stop3822" />
|
||||||
|
</linearGradient>
|
||||||
|
<radialGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient3818"
|
||||||
|
id="radialGradient3824"
|
||||||
|
cx="212.07048"
|
||||||
|
cy="1045.9178"
|
||||||
|
fx="212.07048"
|
||||||
|
fy="1045.9178"
|
||||||
|
r="238.57143"
|
||||||
|
gradientTransform="matrix(1.9491621,-0.90817722,0.65829208,1.4128498,-879.63121,-248.98648)"
|
||||||
|
gradientUnits="userSpaceOnUse" />
|
||||||
|
<radialGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient3913"
|
||||||
|
id="radialGradient3919"
|
||||||
|
cx="362.98563"
|
||||||
|
cy="379.77524"
|
||||||
|
fx="362.98563"
|
||||||
|
fy="379.77524"
|
||||||
|
r="139.95312"
|
||||||
|
gradientTransform="matrix(1.3800477,1.0445431,-1.3325077,1.7605059,339.09383,-577.83938)"
|
||||||
|
gradientUnits="userSpaceOnUse" />
|
||||||
|
<linearGradient
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
y2="-155.75885"
|
||||||
|
x2="114.59022"
|
||||||
|
y1="35.545681"
|
||||||
|
x1="114.55434"
|
||||||
|
id="linearGradient3794"
|
||||||
|
xlink:href="#linearGradient3788"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient3788">
|
||||||
|
<stop
|
||||||
|
id="stop3790"
|
||||||
|
offset="0"
|
||||||
|
style="stop-color:#1eed00;stop-opacity:1;" />
|
||||||
|
<stop
|
||||||
|
id="stop3792"
|
||||||
|
offset="1"
|
||||||
|
style="stop-color:#abff28;stop-opacity:1;" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient3821">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ff283d;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop3823" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ff28ae;stop-opacity:1;"
|
||||||
|
offset="1"
|
||||||
|
id="stop3825" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient4543">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#2e45bf;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop4545" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#28a7ff;stop-opacity:1;"
|
||||||
|
offset="1"
|
||||||
|
id="stop4547" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient4098">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffffff;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop4100" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#e6e6e6;stop-opacity:1"
|
||||||
|
offset="1"
|
||||||
|
id="stop4102" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient4098"
|
||||||
|
id="linearGradient3833"
|
||||||
|
x1="273.81851"
|
||||||
|
y1="764.74677"
|
||||||
|
x2="304.14023"
|
||||||
|
y2="936.47272"
|
||||||
|
gradientUnits="userSpaceOnUse" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient4098"
|
||||||
|
id="linearGradient3853"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
x1="273.81851"
|
||||||
|
y1="764.74677"
|
||||||
|
x2="304.14023"
|
||||||
|
y2="936.47272" />
|
||||||
|
<radialGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient3818"
|
||||||
|
id="radialGradient3863"
|
||||||
|
cx="262.33273"
|
||||||
|
cy="945.23846"
|
||||||
|
fx="262.33273"
|
||||||
|
fy="945.23846"
|
||||||
|
r="185.49754"
|
||||||
|
gradientTransform="matrix(1.2253203,-0.54206726,0.43090148,0.97403458,-466.4135,170.11831)"
|
||||||
|
gradientUnits="userSpaceOnUse" />
|
||||||
|
<radialGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient3818"
|
||||||
|
id="radialGradient3866"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(1.2253203,-0.54206726,0.43090148,0.97403458,-466.4135,170.11831)"
|
||||||
|
cx="262.33273"
|
||||||
|
cy="945.23846"
|
||||||
|
fx="262.33273"
|
||||||
|
fy="945.23846"
|
||||||
|
r="185.49754" />
|
||||||
|
<radialGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient3913"
|
||||||
|
id="radialGradient3873"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(1.3800477,1.0445431,-1.3325077,1.7605059,339.09383,-577.83938)"
|
||||||
|
cx="321.75275"
|
||||||
|
cy="386.38751"
|
||||||
|
fx="321.75275"
|
||||||
|
fy="386.38751"
|
||||||
|
r="139.95312" />
|
||||||
|
<radialGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient3818"
|
||||||
|
id="radialGradient3880"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(1.2253203,-0.54206726,0.43090148,0.97403458,-466.4135,-370.24387)"
|
||||||
|
cx="262.33273"
|
||||||
|
cy="945.23846"
|
||||||
|
fx="262.33273"
|
||||||
|
fy="945.23846"
|
||||||
|
r="185.49754" />
|
||||||
|
<radialGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient3913"
|
||||||
|
id="radialGradient3883"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(1.4430075,-0.63865195,0.50745433,1.1475866,-594.40824,44.803037)"
|
||||||
|
cx="262.33273"
|
||||||
|
cy="945.23846"
|
||||||
|
fx="262.33273"
|
||||||
|
fy="945.23846"
|
||||||
|
r="185.49754" />
|
||||||
|
<radialGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient3874"
|
||||||
|
id="radialGradient3881"
|
||||||
|
cx="150.35715"
|
||||||
|
cy="236.28571"
|
||||||
|
fx="150.35715"
|
||||||
|
fy="236.28571"
|
||||||
|
r="26.887305"
|
||||||
|
gradientTransform="matrix(1,0,0,0.98671703,0,3.1385771)"
|
||||||
|
gradientUnits="userSpaceOnUse" />
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="1.4142136"
|
||||||
|
inkscape:cx="260.34974"
|
||||||
|
inkscape:cy="246.85245"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:window-width="956"
|
||||||
|
inkscape:window-height="1039"
|
||||||
|
inkscape:window-x="960"
|
||||||
|
inkscape:window-y="18"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
showguides="false"
|
||||||
|
inkscape:guide-bbox="true"
|
||||||
|
inkscape:snap-to-guides="true"
|
||||||
|
inkscape:snap-grids="false"
|
||||||
|
inkscape:object-paths="true"
|
||||||
|
inkscape:object-nodes="false"
|
||||||
|
inkscape:snap-nodes="false"
|
||||||
|
inkscape:pagecheckerboard="true">
|
||||||
|
<sodipodi:guide
|
||||||
|
orientation="1,0"
|
||||||
|
position="0,534.28571"
|
||||||
|
id="guide3004"
|
||||||
|
inkscape:locked="false" />
|
||||||
|
<sodipodi:guide
|
||||||
|
orientation="0,1"
|
||||||
|
position="394.28571,511.42857"
|
||||||
|
id="guide3006"
|
||||||
|
inkscape:locked="false" />
|
||||||
|
<sodipodi:guide
|
||||||
|
orientation="1,0"
|
||||||
|
position="511.42857,320"
|
||||||
|
id="guide3008"
|
||||||
|
inkscape:locked="false" />
|
||||||
|
<sodipodi:guide
|
||||||
|
orientation="0,1"
|
||||||
|
position="401.42857,0"
|
||||||
|
id="guide3010"
|
||||||
|
inkscape:locked="false" />
|
||||||
|
<sodipodi:guide
|
||||||
|
orientation="1,0"
|
||||||
|
position="17.142857,258.57143"
|
||||||
|
id="guide3012"
|
||||||
|
inkscape:locked="false" />
|
||||||
|
<sodipodi:guide
|
||||||
|
orientation="0,1"
|
||||||
|
position="327.14286,494.28571"
|
||||||
|
id="guide3014"
|
||||||
|
inkscape:locked="false" />
|
||||||
|
<sodipodi:guide
|
||||||
|
orientation="0,1"
|
||||||
|
position="324.28571,17.142857"
|
||||||
|
id="guide3016"
|
||||||
|
inkscape:locked="false" />
|
||||||
|
<sodipodi:guide
|
||||||
|
orientation="1,0"
|
||||||
|
position="494.28571,237.14286"
|
||||||
|
id="guide3018"
|
||||||
|
inkscape:locked="false" />
|
||||||
|
<sodipodi:guide
|
||||||
|
orientation="1,0"
|
||||||
|
position="255.71429,302.85714"
|
||||||
|
id="guide3022"
|
||||||
|
inkscape:locked="false" />
|
||||||
|
<sodipodi:guide
|
||||||
|
orientation="1,0"
|
||||||
|
position="660,-315"
|
||||||
|
id="guide3904"
|
||||||
|
inkscape:locked="false" />
|
||||||
|
<sodipodi:guide
|
||||||
|
orientation="0,1"
|
||||||
|
position="554.28571,475.71429"
|
||||||
|
id="guide3931"
|
||||||
|
inkscape:locked="false" />
|
||||||
|
<sodipodi:guide
|
||||||
|
orientation="0,1"
|
||||||
|
position="581.42857,244.28571"
|
||||||
|
id="guide3933"
|
||||||
|
inkscape:locked="false" />
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<metadata
|
||||||
|
id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(0,-540.36218)"
|
||||||
|
style="display:inline">
|
||||||
|
<path
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:none"
|
||||||
|
d="m 253.21875,17.71875 c -127.0747,0 -230.75,101.16492 -230.75,226.03125 0,124.86632 103.66932,226.09375 230.75,226.09375 39.52056,0 69.99755,-8.10776 104.78125,-20.75 L 468.46875,493.625 c 11.02016,4.46685 22.45453,-5.45389 19.59375,-17 L 458.125,355.65625 C 477.35631,321.88611 483.9375,283.41561 483.9375,243.75 483.9375,118.88673 380.29349,17.71875 253.21875,17.71875 Z m 127.29102,163.70508 23.93164,23.93164 -141.7461,141.74609 -107.1914,-107.1914 v 72.28125 H 121.6582 v -130.0586 h 130.06055 v 33.84375 h -72.2832 l 83.25976,83.26172 z"
|
||||||
|
transform="translate(0,540.36218)"
|
||||||
|
id="path3868"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="sssccccsscccccccccccc" />
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="ccsssscc"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3845"
|
||||||
|
d="M 478.64112,1025.218 447.36049,898.60749 c 19.89028,-31.99834 26.74288,-69.57172 26.74288,-109.76189 0,-116.81686 -96.79943,-211.48385 -216.18374,-211.48385 -119.38425,0 -216.183656,94.66699 -216.183656,211.48385 0,116.81685 96.799406,211.5536 216.183656,211.5536 39.63617,0 68.58847,-8.14219 105.19417,-21.76075 z"
|
||||||
|
style="opacity:0;fill:none;stroke:#000000;stroke-width:23.55835724;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:94.23343197, 94.23343197;stroke-dashoffset:0" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer4"
|
||||||
|
inkscape:label="Dots" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 11 KiB |
|
@ -28,6 +28,7 @@ images = {
|
||||||
'conversations_mono.svg' => ['conversations/ic_notification', 24],
|
'conversations_mono.svg' => ['conversations/ic_notification', 24],
|
||||||
'quicksy_mono.svg' => ['quicksy/ic_notification', 24],
|
'quicksy_mono.svg' => ['quicksy/ic_notification', 24],
|
||||||
'flip_camera_android-black-24dp.svg' => ['ic_flip_camera_android_black_24dp', 24],
|
'flip_camera_android-black-24dp.svg' => ['ic_flip_camera_android_black_24dp', 24],
|
||||||
|
'ic_missed_call_notification.svg' => ['ic_missed_call_notification', 24],
|
||||||
'ic_send_text_offline.svg' => ['ic_send_text_offline', 36],
|
'ic_send_text_offline.svg' => ['ic_send_text_offline', 36],
|
||||||
'ic_send_text_offline_white.svg' => ['ic_send_text_offline_white', 36],
|
'ic_send_text_offline_white.svg' => ['ic_send_text_offline_white', 36],
|
||||||
'ic_send_text_online.svg' => ['ic_send_text_online', 36],
|
'ic_send_text_online.svg' => ['ic_send_text_online', 36],
|
||||||
|
@ -119,7 +120,7 @@ images.each do |source_filename, settings|
|
||||||
else
|
else
|
||||||
path = "../src/#{output_parts[0]}/res/drawable-#{resolution}/#{output_parts[1]}.png"
|
path = "../src/#{output_parts[0]}/res/drawable-#{resolution}/#{output_parts[1]}.png"
|
||||||
end
|
end
|
||||||
execute_cmd "#{inkscape} #{source_filename} -C -w #{width} -h #{height} -o #{path}"
|
execute_cmd "#{inkscape} #{source_filename} -C -w #{width} -h #{height} -e #{path}"
|
||||||
|
|
||||||
top = []
|
top = []
|
||||||
right = []
|
right = []
|
||||||
|
|
|
@ -241,11 +241,11 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void findUnreadMessages(OnMessageFound onMessageFound) {
|
public void findUnreadMessagesAndCalls(OnMessageFound onMessageFound) {
|
||||||
final ArrayList<Message> results = new ArrayList<>();
|
final ArrayList<Message> results = new ArrayList<>();
|
||||||
synchronized (this.messages) {
|
synchronized (this.messages) {
|
||||||
for (final Message message : this.messages) {
|
for (final Message message : this.messages) {
|
||||||
if (message.isRead() || message.getType() == Message.TYPE_RTP_SESSION) {
|
if (message.isRead()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
results.add(message);
|
results.add(message);
|
||||||
|
|
|
@ -90,17 +90,20 @@ public class NotificationService {
|
||||||
|
|
||||||
private static final long[] CALL_PATTERN = {0, 500, 300, 600};
|
private static final long[] CALL_PATTERN = {0, 500, 300, 600};
|
||||||
|
|
||||||
private static final String CONVERSATIONS_GROUP = "eu.siacs.conversations";
|
private static final String MESSAGES_GROUP = "eu.siacs.conversations.messages";
|
||||||
|
private static final String MISSED_CALLS_GROUP = "eu.siacs.conversations.missed_calls";
|
||||||
private static final int NOTIFICATION_ID_MULTIPLIER = 1024 * 1024;
|
private static final int NOTIFICATION_ID_MULTIPLIER = 1024 * 1024;
|
||||||
static final int FOREGROUND_NOTIFICATION_ID = NOTIFICATION_ID_MULTIPLIER * 4;
|
static final int FOREGROUND_NOTIFICATION_ID = NOTIFICATION_ID_MULTIPLIER * 4;
|
||||||
private static final int NOTIFICATION_ID = NOTIFICATION_ID_MULTIPLIER * 2;
|
private static final int NOTIFICATION_ID = NOTIFICATION_ID_MULTIPLIER * 2;
|
||||||
private static final int ERROR_NOTIFICATION_ID = NOTIFICATION_ID_MULTIPLIER * 6;
|
private static final int ERROR_NOTIFICATION_ID = NOTIFICATION_ID_MULTIPLIER * 6;
|
||||||
private static final int INCOMING_CALL_NOTIFICATION_ID = NOTIFICATION_ID_MULTIPLIER * 8;
|
private static final int INCOMING_CALL_NOTIFICATION_ID = NOTIFICATION_ID_MULTIPLIER * 8;
|
||||||
public static final int ONGOING_CALL_NOTIFICATION_ID = NOTIFICATION_ID_MULTIPLIER * 10;
|
public static final int ONGOING_CALL_NOTIFICATION_ID = NOTIFICATION_ID_MULTIPLIER * 10;
|
||||||
private static final int DELIVERY_FAILED_NOTIFICATION_ID = NOTIFICATION_ID_MULTIPLIER * 12;
|
public static final int MISSED_CALL_NOTIFICATION_ID = NOTIFICATION_ID_MULTIPLIER * 12;
|
||||||
|
private static final int DELIVERY_FAILED_NOTIFICATION_ID = NOTIFICATION_ID_MULTIPLIER * 13;
|
||||||
private final XmppConnectionService mXmppConnectionService;
|
private final XmppConnectionService mXmppConnectionService;
|
||||||
private final LinkedHashMap<String, ArrayList<Message>> notifications = new LinkedHashMap<>();
|
private final LinkedHashMap<String, ArrayList<Message>> notifications = new LinkedHashMap<>();
|
||||||
private final HashMap<Conversation, AtomicInteger> mBacklogMessageCounter = new HashMap<>();
|
private final HashMap<Conversation, AtomicInteger> mBacklogMessageCounter = new HashMap<>();
|
||||||
|
private final LinkedHashMap<Conversational, MissedCallsInfo> mMissedCalls = new LinkedHashMap<>();
|
||||||
private Conversation mOpenConversation;
|
private Conversation mOpenConversation;
|
||||||
private boolean mIsInForeground;
|
private boolean mIsInForeground;
|
||||||
private long mLastNotification;
|
private long mLastNotification;
|
||||||
|
@ -221,6 +224,16 @@ public class NotificationService {
|
||||||
ongoingCallsChannel.setGroup("calls");
|
ongoingCallsChannel.setGroup("calls");
|
||||||
notificationManager.createNotificationChannel(ongoingCallsChannel);
|
notificationManager.createNotificationChannel(ongoingCallsChannel);
|
||||||
|
|
||||||
|
final NotificationChannel missedCallsChannel = new NotificationChannel("missed_calls",
|
||||||
|
c.getString(R.string.missed_calls_channel_name),
|
||||||
|
NotificationManager.IMPORTANCE_HIGH);
|
||||||
|
missedCallsChannel.setShowBadge(true);
|
||||||
|
missedCallsChannel.setSound(null, null);
|
||||||
|
missedCallsChannel.setLightColor(LED_COLOR);
|
||||||
|
missedCallsChannel.enableLights(true);
|
||||||
|
missedCallsChannel.setGroup("calls");
|
||||||
|
notificationManager.createNotificationChannel(missedCallsChannel);
|
||||||
|
|
||||||
final NotificationChannel messagesChannel =
|
final NotificationChannel messagesChannel =
|
||||||
new NotificationChannel(
|
new NotificationChannel(
|
||||||
"messages",
|
"messages",
|
||||||
|
@ -284,12 +297,18 @@ public class NotificationService {
|
||||||
notificationManager.createNotificationChannel(deliveryFailedChannel);
|
notificationManager.createNotificationChannel(deliveryFailedChannel);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean notify(final Message message) {
|
private boolean notifyMessage(final Message message) {
|
||||||
final Conversation conversation = (Conversation) message.getConversation();
|
final Conversation conversation = (Conversation) message.getConversation();
|
||||||
return message.getStatus() == Message.STATUS_RECEIVED
|
return message.getStatus() == Message.STATUS_RECEIVED
|
||||||
&& !conversation.isMuted()
|
&& !conversation.isMuted()
|
||||||
&& (conversation.alwaysNotify() || wasHighlightedOrPrivate(message))
|
&& (conversation.alwaysNotify() || wasHighlightedOrPrivate(message))
|
||||||
&& (!conversation.isWithStranger() || notificationsFromStrangers());
|
&& (!conversation.isWithStranger() || notificationsFromStrangers())
|
||||||
|
&& message.getType() != Message.TYPE_RTP_SESSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean notifyMissedCall(final Message message) {
|
||||||
|
return message.getType() == Message.TYPE_RTP_SESSION
|
||||||
|
&& message.getStatus() == Message.STATUS_RECEIVED;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean notificationsFromStrangers() {
|
public boolean notificationsFromStrangers() {
|
||||||
|
@ -320,12 +339,16 @@ public class NotificationService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void pushFromBacklog(final Message message) {
|
public void pushFromBacklog(final Message message) {
|
||||||
if (notify(message)) {
|
if (notifyMessage(message)) {
|
||||||
synchronized (notifications) {
|
synchronized (notifications) {
|
||||||
getBacklogMessageCounter((Conversation) message.getConversation())
|
getBacklogMessageCounter((Conversation) message.getConversation())
|
||||||
.incrementAndGet();
|
.incrementAndGet();
|
||||||
pushToStack(message);
|
pushToStack(message);
|
||||||
}
|
}
|
||||||
|
} else if (notifyMissedCall(message)) {
|
||||||
|
synchronized (mMissedCalls) {
|
||||||
|
pushMissedCall(message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,6 +383,9 @@ public class NotificationService {
|
||||||
updateNotification(count > 0, conversations);
|
updateNotification(count > 0, conversations);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
synchronized (mMissedCalls) {
|
||||||
|
updateMissedCallNotifications(mMissedCalls.keySet());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> getBacklogConversations(Account account) {
|
private List<String> getBacklogConversations(Account account) {
|
||||||
|
@ -666,7 +692,7 @@ public class NotificationService {
|
||||||
|
|
||||||
private void pushNow(final Message message) {
|
private void pushNow(final Message message) {
|
||||||
mXmppConnectionService.updateUnreadCountBadge();
|
mXmppConnectionService.updateUnreadCountBadge();
|
||||||
if (!notify(message)) {
|
if (!notifyMessage(message)) {
|
||||||
Log.d(
|
Log.d(
|
||||||
Config.LOGTAG,
|
Config.LOGTAG,
|
||||||
message.getConversation().getAccount().getJid().asBareJid()
|
message.getConversation().getAccount().getJid().asBareJid()
|
||||||
|
@ -695,7 +721,29 @@ public class NotificationService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clear() {
|
private void pushMissedCall(final Message message) {
|
||||||
|
final Conversational conversation = message.getConversation();
|
||||||
|
final MissedCallsInfo info = mMissedCalls.get(conversation);
|
||||||
|
if (info == null) {
|
||||||
|
mMissedCalls.put(conversation, new MissedCallsInfo(message.getTimeSent()));
|
||||||
|
} else {
|
||||||
|
info.newMissedCall(message.getTimeSent());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void pushMissedCallNow(final Message message) {
|
||||||
|
synchronized (mMissedCalls) {
|
||||||
|
pushMissedCall(message);
|
||||||
|
updateMissedCallNotifications(Collections.singleton(message.getConversation()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear(final Conversation conversation) {
|
||||||
|
clearMessages(conversation);
|
||||||
|
clearMissedCalls(conversation);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearMessages() {
|
||||||
synchronized (notifications) {
|
synchronized (notifications) {
|
||||||
for (ArrayList<Message> messages : notifications.values()) {
|
for (ArrayList<Message> messages : notifications.values()) {
|
||||||
markAsReadIfHasDirectReply(messages);
|
markAsReadIfHasDirectReply(messages);
|
||||||
|
@ -705,7 +753,7 @@ public class NotificationService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clear(final Conversation conversation) {
|
public void clearMessages(final Conversation conversation) {
|
||||||
synchronized (this.mBacklogMessageCounter) {
|
synchronized (this.mBacklogMessageCounter) {
|
||||||
this.mBacklogMessageCounter.remove(conversation);
|
this.mBacklogMessageCounter.remove(conversation);
|
||||||
}
|
}
|
||||||
|
@ -718,6 +766,25 @@ public class NotificationService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clearMissedCalls() {
|
||||||
|
synchronized (mMissedCalls) {
|
||||||
|
for (final Conversational conversation : mMissedCalls.keySet()) {
|
||||||
|
cancel(conversation.getUuid(), MISSED_CALL_NOTIFICATION_ID);
|
||||||
|
}
|
||||||
|
mMissedCalls.clear();
|
||||||
|
updateMissedCallNotifications(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearMissedCalls(final Conversation conversation) {
|
||||||
|
synchronized (mMissedCalls) {
|
||||||
|
if (mMissedCalls.remove(conversation) != null) {
|
||||||
|
cancel(conversation.getUuid(), MISSED_CALL_NOTIFICATION_ID);
|
||||||
|
updateMissedCallNotifications(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void markAsReadIfHasDirectReply(final Conversation conversation) {
|
private void markAsReadIfHasDirectReply(final Conversation conversation) {
|
||||||
markAsReadIfHasDirectReply(notifications.get(conversation.getUuid()));
|
markAsReadIfHasDirectReply(notifications.get(conversation.getUuid()));
|
||||||
}
|
}
|
||||||
|
@ -797,7 +864,7 @@ public class NotificationService {
|
||||||
}
|
}
|
||||||
modifyForSoundVibrationAndLight(
|
modifyForSoundVibrationAndLight(
|
||||||
singleBuilder, notifyThis, quiteHours, preferences);
|
singleBuilder, notifyThis, quiteHours, preferences);
|
||||||
singleBuilder.setGroup(CONVERSATIONS_GROUP);
|
singleBuilder.setGroup(MESSAGES_GROUP);
|
||||||
setNotificationColor(singleBuilder);
|
setNotificationColor(singleBuilder);
|
||||||
notify(entry.getKey(), NOTIFICATION_ID, singleBuilder.build());
|
notify(entry.getKey(), NOTIFICATION_ID, singleBuilder.build());
|
||||||
}
|
}
|
||||||
|
@ -807,6 +874,31 @@ public class NotificationService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateMissedCallNotifications(final Set<Conversational> update) {
|
||||||
|
if (mMissedCalls.isEmpty()) {
|
||||||
|
cancel(MISSED_CALL_NOTIFICATION_ID);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (mMissedCalls.size() == 1 && Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
|
||||||
|
final Conversational conversation = mMissedCalls.keySet().iterator().next();
|
||||||
|
final MissedCallsInfo info = mMissedCalls.values().iterator().next();
|
||||||
|
final Notification notification = missedCall(conversation, info);
|
||||||
|
notify(MISSED_CALL_NOTIFICATION_ID, notification);
|
||||||
|
} else {
|
||||||
|
final Notification summary = missedCallsSummary();
|
||||||
|
notify(MISSED_CALL_NOTIFICATION_ID, summary);
|
||||||
|
if (update != null) {
|
||||||
|
for (final Conversational conversation : update) {
|
||||||
|
final MissedCallsInfo info = mMissedCalls.get(conversation);
|
||||||
|
if (info != null) {
|
||||||
|
final Notification notification = missedCall(conversation, info);
|
||||||
|
notify(conversation.getUuid(), MISSED_CALL_NOTIFICATION_ID, notification);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void modifyForSoundVibrationAndLight(
|
private void modifyForSoundVibrationAndLight(
|
||||||
Builder mBuilder, boolean notify, boolean quietHours, SharedPreferences preferences) {
|
Builder mBuilder, boolean notify, boolean quietHours, SharedPreferences preferences) {
|
||||||
final Resources resources = mXmppConnectionService.getResources();
|
final Resources resources = mXmppConnectionService.getResources();
|
||||||
|
@ -867,6 +959,101 @@ public class NotificationService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Notification missedCallsSummary() {
|
||||||
|
final Builder publicBuilder = buildMissedCallsSummary(true);
|
||||||
|
final Builder builder = buildMissedCallsSummary(false);
|
||||||
|
builder.setPublicVersion(publicBuilder.build());
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Builder buildMissedCallsSummary(boolean publicVersion) {
|
||||||
|
final Builder builder = new NotificationCompat.Builder(mXmppConnectionService, "missed_calls");
|
||||||
|
int totalCalls = 0;
|
||||||
|
final StringBuilder names = new StringBuilder();
|
||||||
|
long lastTime = 0;
|
||||||
|
for (Map.Entry<Conversational, MissedCallsInfo> entry : mMissedCalls.entrySet()) {
|
||||||
|
final Conversational conversation = entry.getKey();
|
||||||
|
final MissedCallsInfo missedCallsInfo = entry.getValue();
|
||||||
|
names.append(conversation.getContact().getDisplayName());
|
||||||
|
names.append(", ");
|
||||||
|
totalCalls += missedCallsInfo.getNumberOfCalls();
|
||||||
|
lastTime = Math.max(lastTime, missedCallsInfo.getLastTime());
|
||||||
|
}
|
||||||
|
if (names.length() >= 2) {
|
||||||
|
names.delete(names.length() - 2, names.length());
|
||||||
|
}
|
||||||
|
final String title = (totalCalls == 1) ? mXmppConnectionService.getString(R.string.missed_call) :
|
||||||
|
(mMissedCalls.size() == 1) ? mXmppConnectionService.getString(R.string.n_missed_calls, totalCalls) :
|
||||||
|
mXmppConnectionService.getString(R.string.n_missed_calls_from_m_contacts, totalCalls, mMissedCalls.size());
|
||||||
|
builder.setContentTitle(title);
|
||||||
|
builder.setTicker(title);
|
||||||
|
if (!publicVersion) {
|
||||||
|
builder.setContentText(names.toString());
|
||||||
|
}
|
||||||
|
builder.setSmallIcon(R.drawable.ic_missed_call_notification);
|
||||||
|
builder.setGroupSummary(true);
|
||||||
|
builder.setGroup(MISSED_CALLS_GROUP);
|
||||||
|
builder.setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_CHILDREN);
|
||||||
|
builder.setCategory(NotificationCompat.CATEGORY_CALL);
|
||||||
|
builder.setWhen(lastTime);
|
||||||
|
if (!mMissedCalls.isEmpty()) {
|
||||||
|
final Conversational firstConversation = mMissedCalls.keySet().iterator().next();
|
||||||
|
builder.setContentIntent(createContentIntent(firstConversation));
|
||||||
|
}
|
||||||
|
builder.setDeleteIntent(createMissedCallsDeleteIntent(null));
|
||||||
|
modifyMissedCall(builder);
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Notification missedCall(final Conversational conversation, final MissedCallsInfo info) {
|
||||||
|
final Builder publicBuilder = buildMissedCall(conversation, info, true);
|
||||||
|
final Builder builder = buildMissedCall(conversation, info, false);
|
||||||
|
builder.setPublicVersion(publicBuilder.build());
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Builder buildMissedCall(final Conversational conversation, final MissedCallsInfo info, boolean publicVersion) {
|
||||||
|
final Builder builder = new NotificationCompat.Builder(mXmppConnectionService, "missed_calls");
|
||||||
|
final String title = (info.getNumberOfCalls() == 1) ? mXmppConnectionService.getString(R.string.missed_call) :
|
||||||
|
mXmppConnectionService.getString(R.string.n_missed_calls, info.getNumberOfCalls());
|
||||||
|
builder.setContentTitle(title);
|
||||||
|
final String name = conversation.getContact().getDisplayName();
|
||||||
|
if (publicVersion) {
|
||||||
|
builder.setTicker(title);
|
||||||
|
} else {
|
||||||
|
if (info.getNumberOfCalls() == 1) {
|
||||||
|
builder.setTicker(mXmppConnectionService.getString(R.string.missed_call_from_x, name));
|
||||||
|
} else {
|
||||||
|
builder.setTicker(mXmppConnectionService.getString(R.string.n_missed_calls_from_x, info.getNumberOfCalls(), name));
|
||||||
|
}
|
||||||
|
builder.setContentText(name);
|
||||||
|
}
|
||||||
|
builder.setSmallIcon(R.drawable.ic_missed_call_notification);
|
||||||
|
builder.setGroup(MISSED_CALLS_GROUP);
|
||||||
|
builder.setCategory(NotificationCompat.CATEGORY_CALL);
|
||||||
|
builder.setWhen(info.getLastTime());
|
||||||
|
builder.setContentIntent(createContentIntent(conversation));
|
||||||
|
builder.setDeleteIntent(createMissedCallsDeleteIntent(conversation));
|
||||||
|
if (!publicVersion && conversation instanceof Conversation) {
|
||||||
|
builder.setLargeIcon(mXmppConnectionService.getAvatarService()
|
||||||
|
.get((Conversation) conversation, AvatarService.getSystemUiAvatarSize(mXmppConnectionService)));
|
||||||
|
}
|
||||||
|
modifyMissedCall(builder);
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void modifyMissedCall(final Builder builder) {
|
||||||
|
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(mXmppConnectionService);
|
||||||
|
final Resources resources = mXmppConnectionService.getResources();
|
||||||
|
final boolean led = preferences.getBoolean("led", resources.getBoolean(R.bool.led));
|
||||||
|
if (led) {
|
||||||
|
builder.setLights(LED_COLOR, 2000, 3000);
|
||||||
|
}
|
||||||
|
builder.setPriority(NotificationCompat.PRIORITY_HIGH);
|
||||||
|
builder.setSound(null);
|
||||||
|
setNotificationColor(builder);
|
||||||
|
}
|
||||||
|
|
||||||
private Builder buildMultipleConversation(final boolean notify, final boolean quietHours) {
|
private Builder buildMultipleConversation(final boolean notify, final boolean quietHours) {
|
||||||
final Builder mBuilder =
|
final Builder mBuilder =
|
||||||
new NotificationCompat.Builder(
|
new NotificationCompat.Builder(
|
||||||
|
@ -932,7 +1119,7 @@ public class NotificationService {
|
||||||
mBuilder.setContentIntent(createContentIntent(conversation));
|
mBuilder.setContentIntent(createContentIntent(conversation));
|
||||||
}
|
}
|
||||||
mBuilder.setGroupSummary(true);
|
mBuilder.setGroupSummary(true);
|
||||||
mBuilder.setGroup(CONVERSATIONS_GROUP);
|
mBuilder.setGroup(MESSAGES_GROUP);
|
||||||
mBuilder.setDeleteIntent(createDeleteIntent(null));
|
mBuilder.setDeleteIntent(createDeleteIntent(null));
|
||||||
mBuilder.setSmallIcon(R.drawable.ic_notification);
|
mBuilder.setSmallIcon(R.drawable.ic_notification);
|
||||||
return mBuilder;
|
return mBuilder;
|
||||||
|
@ -1336,7 +1523,7 @@ public class NotificationService {
|
||||||
|
|
||||||
private PendingIntent createDeleteIntent(Conversation conversation) {
|
private PendingIntent createDeleteIntent(Conversation conversation) {
|
||||||
final Intent intent = new Intent(mXmppConnectionService, XmppConnectionService.class);
|
final Intent intent = new Intent(mXmppConnectionService, XmppConnectionService.class);
|
||||||
intent.setAction(XmppConnectionService.ACTION_CLEAR_NOTIFICATION);
|
intent.setAction(XmppConnectionService.ACTION_CLEAR_MESSAGE_NOTIFICATION);
|
||||||
if (conversation != null) {
|
if (conversation != null) {
|
||||||
intent.putExtra("uuid", conversation.getUuid());
|
intent.putExtra("uuid", conversation.getUuid());
|
||||||
return PendingIntent.getService(
|
return PendingIntent.getService(
|
||||||
|
@ -1356,6 +1543,16 @@ public class NotificationService {
|
||||||
: PendingIntent.FLAG_UPDATE_CURRENT);
|
: PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private PendingIntent createMissedCallsDeleteIntent(final Conversational conversation) {
|
||||||
|
final Intent intent = new Intent(mXmppConnectionService, XmppConnectionService.class);
|
||||||
|
intent.setAction(XmppConnectionService.ACTION_CLEAR_MISSED_CALL_NOTIFICATION);
|
||||||
|
if (conversation != null) {
|
||||||
|
intent.putExtra("uuid", conversation.getUuid());
|
||||||
|
return PendingIntent.getService(mXmppConnectionService, generateRequestCode(conversation, 21), intent, 0);
|
||||||
|
}
|
||||||
|
return PendingIntent.getService(mXmppConnectionService, 1, intent, 0);
|
||||||
|
}
|
||||||
|
|
||||||
private PendingIntent createReplyIntent(
|
private PendingIntent createReplyIntent(
|
||||||
final Conversation conversation,
|
final Conversation conversation,
|
||||||
final String lastMessageUuid,
|
final String lastMessageUuid,
|
||||||
|
@ -1677,6 +1874,28 @@ public class NotificationService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class MissedCallsInfo {
|
||||||
|
private int numberOfCalls;
|
||||||
|
private long lastTime;
|
||||||
|
|
||||||
|
MissedCallsInfo(final long time) {
|
||||||
|
numberOfCalls = 1;
|
||||||
|
lastTime = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void newMissedCall(final long time) {
|
||||||
|
++numberOfCalls;
|
||||||
|
lastTime = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNumberOfCalls() {
|
||||||
|
return numberOfCalls;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getLastTime() {
|
||||||
|
return lastTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
private class VibrationRunnable implements Runnable {
|
private class VibrationRunnable implements Runnable {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -175,7 +175,8 @@ public class XmppConnectionService extends Service {
|
||||||
public static final String ACTION_REPLY_TO_CONVERSATION = "reply_to_conversations";
|
public static final String ACTION_REPLY_TO_CONVERSATION = "reply_to_conversations";
|
||||||
public static final String ACTION_MARK_AS_READ = "mark_as_read";
|
public static final String ACTION_MARK_AS_READ = "mark_as_read";
|
||||||
public static final String ACTION_SNOOZE = "snooze";
|
public static final String ACTION_SNOOZE = "snooze";
|
||||||
public static final String ACTION_CLEAR_NOTIFICATION = "clear_notification";
|
public static final String ACTION_CLEAR_MESSAGE_NOTIFICATION = "clear_message_notification";
|
||||||
|
public static final String ACTION_CLEAR_MISSED_CALL_NOTIFICATION = "clear_missed_call_notification";
|
||||||
public static final String ACTION_DISMISS_ERROR_NOTIFICATIONS = "dismiss_error";
|
public static final String ACTION_DISMISS_ERROR_NOTIFICATIONS = "dismiss_error";
|
||||||
public static final String ACTION_TRY_AGAIN = "try_again";
|
public static final String ACTION_TRY_AGAIN = "try_again";
|
||||||
public static final String ACTION_IDLE_PING = "idle_ping";
|
public static final String ACTION_IDLE_PING = "idle_ping";
|
||||||
|
@ -670,19 +671,35 @@ public class XmppConnectionService extends Service {
|
||||||
case Intent.ACTION_SHUTDOWN:
|
case Intent.ACTION_SHUTDOWN:
|
||||||
logoutAndSave(true);
|
logoutAndSave(true);
|
||||||
return START_NOT_STICKY;
|
return START_NOT_STICKY;
|
||||||
case ACTION_CLEAR_NOTIFICATION:
|
case ACTION_CLEAR_MESSAGE_NOTIFICATION:
|
||||||
mNotificationExecutor.execute(() -> {
|
mNotificationExecutor.execute(() -> {
|
||||||
try {
|
try {
|
||||||
final Conversation c = findConversationByUuid(uuid);
|
final Conversation c = findConversationByUuid(uuid);
|
||||||
if (c != null) {
|
if (c != null) {
|
||||||
mNotificationService.clear(c);
|
mNotificationService.clearMessages(c);
|
||||||
} else {
|
} else {
|
||||||
mNotificationService.clear();
|
mNotificationService.clearMessages();
|
||||||
}
|
}
|
||||||
restoredFromDatabaseLatch.await();
|
restoredFromDatabaseLatch.await();
|
||||||
|
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
Log.d(Config.LOGTAG, "unable to process clear notification");
|
Log.d(Config.LOGTAG, "unable to process clear message notification");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case ACTION_CLEAR_MISSED_CALL_NOTIFICATION:
|
||||||
|
mNotificationExecutor.execute(() -> {
|
||||||
|
try {
|
||||||
|
final Conversation c = findConversationByUuid(uuid);
|
||||||
|
if (c != null) {
|
||||||
|
mNotificationService.clearMissedCalls(c);
|
||||||
|
} else {
|
||||||
|
mNotificationService.clearMissedCalls();
|
||||||
|
}
|
||||||
|
restoredFromDatabaseLatch.await();
|
||||||
|
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Log.d(Config.LOGTAG, "unable to process clear missed call notification");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
@ -769,7 +786,7 @@ public class XmppConnectionService extends Service {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
c.setMutedTill(System.currentTimeMillis() + 30 * 60 * 1000);
|
c.setMutedTill(System.currentTimeMillis() + 30 * 60 * 1000);
|
||||||
mNotificationService.clear(c);
|
mNotificationService.clearMessages(c);
|
||||||
updateConversation(c);
|
updateConversation(c);
|
||||||
});
|
});
|
||||||
case AudioManager.RINGER_MODE_CHANGED_ACTION:
|
case AudioManager.RINGER_MODE_CHANGED_ACTION:
|
||||||
|
@ -1954,7 +1971,7 @@ public class XmppConnectionService extends Service {
|
||||||
private void restoreMessages(Conversation conversation) {
|
private void restoreMessages(Conversation conversation) {
|
||||||
conversation.addAll(0, databaseBackend.getMessages(conversation, Config.PAGE_SIZE));
|
conversation.addAll(0, databaseBackend.getMessages(conversation, Config.PAGE_SIZE));
|
||||||
conversation.findUnsentTextMessages(message -> markMessage(message, Message.STATUS_WAITING));
|
conversation.findUnsentTextMessages(message -> markMessage(message, Message.STATUS_WAITING));
|
||||||
conversation.findUnreadMessages(mNotificationService::pushFromBacklog);
|
conversation.findUnreadMessagesAndCalls(mNotificationService::pushFromBacklog);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadPhoneContacts() {
|
public void loadPhoneContacts() {
|
||||||
|
|
|
@ -1110,6 +1110,7 @@ public class JingleRtpConnection extends AbstractJingleConnection
|
||||||
rejectCallFromSessionInitiate();
|
rejectCallFromSessionInitiate();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
xmppConnectionService.getNotificationService().pushMissedCallNow(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cancelRingingTimeout() {
|
private void cancelRingingTimeout() {
|
||||||
|
@ -1187,6 +1188,7 @@ public class JingleRtpConnection extends AbstractJingleConnection
|
||||||
this.state == State.PROCEED ? State.RETRACTED_RACED : State.RETRACTED;
|
this.state == State.PROCEED ? State.RETRACTED_RACED : State.RETRACTED;
|
||||||
if (transition(target)) {
|
if (transition(target)) {
|
||||||
xmppConnectionService.getNotificationService().cancelIncomingCallNotification();
|
xmppConnectionService.getNotificationService().cancelIncomingCallNotification();
|
||||||
|
xmppConnectionService.getNotificationService().pushMissedCallNow(message);
|
||||||
Log.d(
|
Log.d(
|
||||||
Config.LOGTAG,
|
Config.LOGTAG,
|
||||||
id.account.getJid().asBareJid()
|
id.account.getJid().asBareJid()
|
||||||
|
|
BIN
src/main/res/drawable-hdpi/ic_missed_call_notification.png
Normal file
BIN
src/main/res/drawable-hdpi/ic_missed_call_notification.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 810 B |
BIN
src/main/res/drawable-mdpi/ic_missed_call_notification.png
Normal file
BIN
src/main/res/drawable-mdpi/ic_missed_call_notification.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 589 B |
BIN
src/main/res/drawable-xhdpi/ic_missed_call_notification.png
Normal file
BIN
src/main/res/drawable-xhdpi/ic_missed_call_notification.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
BIN
src/main/res/drawable-xxhdpi/ic_missed_call_notification.png
Normal file
BIN
src/main/res/drawable-xxhdpi/ic_missed_call_notification.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
BIN
src/main/res/drawable-xxxhdpi/ic_missed_call_notification.png
Normal file
BIN
src/main/res/drawable-xxxhdpi/ic_missed_call_notification.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
|
@ -767,6 +767,7 @@
|
||||||
<string name="messages_channel_name">Messages</string>
|
<string name="messages_channel_name">Messages</string>
|
||||||
<string name="incoming_calls_channel_name">Incoming calls</string>
|
<string name="incoming_calls_channel_name">Incoming calls</string>
|
||||||
<string name="ongoing_calls_channel_name">Ongoing calls</string>
|
<string name="ongoing_calls_channel_name">Ongoing calls</string>
|
||||||
|
<string name="missed_calls_channel_name">Missed calls</string>
|
||||||
<string name="silent_messages_channel_name">Silent messages</string>
|
<string name="silent_messages_channel_name">Silent messages</string>
|
||||||
<string name="silent_messages_channel_description">This notification group is used to display notifications that should not trigger any sound. For example when being active on another device (Grace Period).</string>
|
<string name="silent_messages_channel_description">This notification group is used to display notifications that should not trigger any sound. For example when being active on another device (Grace Period).</string>
|
||||||
<string name="delivery_failed_channel_name">Failed deliveries</string>
|
<string name="delivery_failed_channel_name">Failed deliveries</string>
|
||||||
|
@ -934,6 +935,10 @@
|
||||||
<string name="outgoing_call">Outgoing call</string>
|
<string name="outgoing_call">Outgoing call</string>
|
||||||
<string name="outgoing_call_duration">Outgoing call · %s</string>
|
<string name="outgoing_call_duration">Outgoing call · %s</string>
|
||||||
<string name="missed_call">Missed call</string>
|
<string name="missed_call">Missed call</string>
|
||||||
|
<string name="missed_call_from_x">Missed call from %s</string>
|
||||||
|
<string name="n_missed_calls_from_x">%1$d missed calls from %2$s</string>
|
||||||
|
<string name="n_missed_calls">%d missed calls</string>
|
||||||
|
<string name="n_missed_calls_from_m_contacts">%1$d missed calls from %2$d contacts</string>
|
||||||
<string name="audio_call">Audio call</string>
|
<string name="audio_call">Audio call</string>
|
||||||
<string name="video_call">Video call</string>
|
<string name="video_call">Video call</string>
|
||||||
<string name="help">Help</string>
|
<string name="help">Help</string>
|
||||||
|
|
Loading…
Reference in a new issue