The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2102 lines
109KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE 7 technical preview.
  4. Copyright (c) 2022 - Raw Material Software Limited
  5. You may use this code under the terms of the GPL v3
  6. (see www.gnu.org/licenses).
  7. For the technical preview this file cannot be licensed commercially.
  8. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  9. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  10. DISCLAIMED.
  11. ==============================================================================
  12. */
  13. namespace juce
  14. {
  15. // This byte-code is generated from native/java/com/rmsl/juce/ComponentPeerView.java with min sdk version 16
  16. // See juce_core/native/java/README.txt on how to generate this byte-code.
  17. static const uint8 javaComponentPeerView[] =
  18. { 31,139,8,8,217,126,216,97,0,3,74,97,118,97,68,101,120,66,121,116,101,67,111,100,101,46,100,101,120,0,165,155,11,124,212,213,149,199,207,189,255,255,204,36,147,215,100,18,146,64,18,50,9,175,16,72,102,8,111,19,148,183,6,18,64,18,16,18,171,76,146,127,146,
  19. 129,201,127,134,153,73,72,124,21,149,143,96,173,21,45,82,21,109,177,165,182,110,109,215,90,219,181,22,181,93,93,215,173,186,85,107,87,180,90,31,69,197,150,90,180,86,105,117,117,127,247,49,147,9,143,210,118,195,231,59,231,252,207,125,223,123,238,185,247,
  20. 63,33,221,214,144,59,48,115,54,125,253,172,186,247,86,249,42,166,141,253,112,218,236,231,195,83,47,91,120,183,99,205,99,123,255,208,184,125,22,81,148,136,134,214,207,242,146,254,57,56,147,168,146,41,251,60,240,129,73,180,4,242,121,7,81,9,228,241,12,162,
  21. 203,33,31,200,36,66,18,237,207,33,218,52,153,200,151,75,212,94,78,116,33,184,24,116,130,205,192,6,215,128,107,193,245,96,55,216,3,110,1,251,192,215,192,195,224,5,240,18,248,13,120,3,188,5,126,15,142,129,63,131,156,241,232,7,184,8,12,131,61,224,126,240,
  22. 60,248,12,140,173,32,170,7,231,130,207,129,65,112,19,120,8,60,7,142,130,137,62,162,101,96,8,220,3,14,131,194,74,162,6,208,11,246,130,23,64,69,21,198,2,46,7,119,130,159,129,195,192,152,64,84,14,2,160,13,92,2,110,0,247,129,199,193,155,224,47,160,122,34,
  23. 209,82,208,1,194,224,10,176,3,220,4,110,6,183,130,253,224,0,184,7,220,7,126,12,30,1,143,129,39,192,211,224,57,240,2,120,5,188,14,222,1,71,193,123,224,35,240,9,48,38,17,101,130,28,224,5,227,64,37,152,4,166,130,5,96,45,184,8,108,6,131,224,42,240,37,112,
  24. 27,184,11,220,7,30,6,79,130,151,192,49,112,28,56,176,174,121,160,6,204,6,243,192,74,208,10,58,64,23,8,131,56,216,14,174,7,119,128,123,192,15,193,65,240,34,120,21,188,1,222,1,89,83,136,138,64,57,152,6,230,129,117,32,14,174,0,55,128,187,192,15,193,35,224,
  25. 73,240,34,56,12,254,2,114,171,137,202,192,20,48,15,44,7,171,193,6,96,129,109,96,39,184,29,124,7,252,4,188,8,94,5,111,130,35,128,79,37,42,0,147,192,92,176,28,180,130,16,184,4,92,7,110,3,223,2,7,193,227,224,85,240,14,248,35,120,31,124,10,140,26,248,15,
  26. 152,0,102,129,115,64,11,184,0,92,12,182,128,1,176,27,236,3,7,192,67,224,41,240,75,240,6,56,2,142,129,227,224,99,192,166,17,185,65,33,168,2,53,32,0,230,128,38,112,17,136,130,171,193,126,240,3,240,56,120,21,188,13,62,4,206,233,40,15,42,64,29,152,11,22,
  27. 129,53,224,34,208,3,34,96,24,108,7,95,4,251,192,215,193,207,192,99,224,105,240,30,200,171,197,122,129,82,48,13,204,7,107,65,39,136,130,47,128,59,193,195,224,73,240,18,120,11,124,8,204,58,204,51,152,0,234,65,51,88,11,54,128,77,160,15,216,32,14,134,193,
  28. 213,224,26,112,61,216,11,110,7,223,5,15,128,159,131,23,193,155,224,8,248,61,248,35,248,19,248,8,124,12,62,3,78,196,36,132,40,202,2,69,160,152,84,220,26,11,198,129,82,80,6,16,82,8,97,131,16,22,8,97,128,176,237,9,91,156,176,125,9,219,138,224,254,4,119,
  29. 37,184,28,193,101,8,203,77,88,30,194,244,18,166,133,48,60,66,115,228,7,1,48,3,212,3,132,79,66,88,165,217,96,14,152,171,227,232,124,112,22,104,0,141,96,1,56,27,156,3,22,130,69,96,49,169,88,187,12,156,7,54,128,78,208,5,186,129,69,106,124,201,31,151,150,
  30. 247,151,170,49,51,253,236,214,186,176,139,121,224,218,158,173,245,131,176,231,165,213,229,213,115,246,152,182,231,106,123,158,78,75,234,99,180,238,209,243,42,234,47,208,250,83,186,108,73,90,157,98,174,159,47,85,186,152,227,151,117,158,201,105,245,76,
  31. 213,245,228,107,253,48,244,66,173,31,45,85,109,138,57,255,64,215,35,244,79,116,61,181,186,158,49,122,29,204,50,213,31,177,22,217,101,106,14,235,117,158,38,173,139,182,86,104,189,16,121,86,106,93,180,219,172,117,31,236,45,90,15,64,95,165,245,70,232,171,
  32. 181,126,30,244,53,90,111,131,126,190,214,47,132,222,170,245,238,52,123,56,77,79,64,95,167,245,203,210,236,187,210,244,221,105,250,45,105,117,238,79,179,127,27,122,155,214,239,77,179,31,40,29,209,197,156,175,213,186,152,207,100,61,15,164,229,23,243,185,
  33. 94,235,63,133,253,2,173,63,145,150,231,80,154,254,90,153,242,205,153,122,110,55,106,253,8,236,237,90,63,150,166,127,2,189,67,235,25,226,142,160,117,15,244,207,105,189,76,220,27,180,94,13,253,34,173,7,210,236,194,199,54,105,125,30,236,65,173,159,151,150,
  34. 191,173,92,248,57,163,97,82,50,135,137,125,63,137,226,164,228,191,73,201,232,65,45,15,106,249,144,150,15,107,249,136,206,255,115,18,177,194,71,110,166,100,1,19,113,99,38,253,23,9,89,65,89,76,196,16,149,94,161,211,43,144,82,196,132,207,23,209,86,225,79,
  35. 216,117,15,72,89,65,79,72,89,78,191,148,114,38,189,35,101,22,29,149,62,63,153,150,67,58,16,129,254,68,98,127,58,233,70,41,199,208,126,200,76,68,49,67,202,89,244,33,137,125,94,45,159,179,180,61,11,17,225,35,57,110,245,156,135,118,111,144,178,136,110,210,
  36. 207,183,106,121,167,152,127,157,46,228,110,41,77,186,89,63,239,147,210,160,219,73,237,211,59,180,252,170,148,140,238,210,242,91,36,246,37,167,189,82,78,165,111,146,216,131,147,100,251,5,136,120,191,149,114,62,29,150,178,148,222,38,177,95,107,105,64,203,
  37. 15,72,196,233,57,244,31,36,226,72,54,61,47,229,88,122,159,68,44,81,227,24,139,136,43,100,25,162,230,143,164,172,161,191,74,121,14,153,114,93,2,50,189,28,51,176,67,202,18,218,165,159,175,149,114,30,189,43,215,171,78,230,27,143,26,95,39,177,78,170,92,5,
  38. 236,61,90,246,74,153,71,125,82,142,37,7,83,210,41,215,115,178,204,239,195,10,133,164,244,211,102,41,23,209,22,41,11,40,172,101,191,148,11,201,150,114,44,13,105,121,185,148,115,233,74,41,43,233,58,41,189,116,189,148,57,244,37,41,157,180,71,251,205,94,
  39. 157,254,21,41,103,211,45,82,102,210,215,164,116,211,215,117,190,111,72,153,65,7,164,84,235,32,252,236,110,41,203,232,95,180,252,142,150,247,104,127,252,174,148,227,233,123,218,254,175,186,220,189,90,126,95,203,251,164,244,209,15,164,108,160,251,165,156,
  40. 67,143,105,249,184,148,19,232,5,41,171,232,144,150,47,106,249,146,78,255,181,126,126,89,203,87,164,204,165,223,72,57,133,94,149,114,58,189,38,229,217,244,134,148,202,143,124,218,143,196,243,155,122,255,188,37,165,242,43,145,255,136,148,141,116,76,202,
  41. 122,58,174,229,95,164,156,70,159,72,57,142,62,149,114,6,125,166,159,137,169,124,76,75,206,84,186,193,212,188,20,50,113,110,21,211,109,36,228,98,122,84,238,87,78,63,147,50,159,188,76,156,77,202,95,167,97,103,124,153,196,249,100,208,21,82,114,122,154,196,
  42. 25,85,72,255,78,226,190,48,86,251,171,218,83,201,51,19,175,88,116,33,98,220,21,250,208,26,175,237,226,204,19,49,93,164,39,32,239,208,233,21,186,252,180,180,242,59,144,126,175,78,247,145,58,87,197,153,120,143,46,191,7,242,144,78,23,119,129,169,208,3,245,
  43. 234,190,112,86,189,178,173,134,92,15,12,157,190,9,108,214,121,226,210,110,72,157,251,213,189,161,131,185,41,234,17,55,168,14,158,133,181,204,64,45,162,173,28,191,186,59,121,89,91,167,155,182,122,102,193,158,197,139,240,218,56,131,115,115,62,55,201,229,
  44. 201,167,182,206,44,218,234,171,160,24,118,191,200,215,214,165,242,26,148,101,110,93,51,135,22,15,184,249,124,254,135,207,108,143,24,143,203,83,253,182,169,219,159,224,87,119,152,42,204,104,212,115,153,28,173,104,91,244,187,214,175,238,96,167,107,219,
  45. 160,124,230,245,206,156,50,246,228,54,3,115,105,177,35,27,49,227,24,218,20,113,202,205,108,223,20,68,169,108,86,253,214,201,185,231,201,220,213,239,136,248,107,202,254,44,241,171,181,107,139,170,124,34,165,136,203,123,9,159,143,60,94,196,151,182,173,
  46. 238,244,116,206,118,176,155,93,119,109,115,206,199,200,16,215,143,25,232,175,24,227,106,191,136,247,152,89,111,14,198,184,13,54,47,93,232,201,150,119,180,12,60,137,177,110,240,171,179,182,192,89,72,85,60,27,249,196,44,180,197,115,168,109,102,46,217,158,
  47. 165,200,149,205,230,179,198,17,155,239,60,236,197,145,28,139,144,195,109,172,157,40,222,21,25,125,191,237,70,50,204,217,155,198,209,186,56,230,193,40,34,175,113,33,180,100,254,182,68,14,250,29,192,72,178,77,209,127,83,206,195,108,90,226,16,249,231,27,
  48. 46,154,187,201,65,222,2,81,70,180,85,140,56,103,123,138,196,200,78,104,163,250,191,197,90,10,159,187,218,175,238,116,29,222,92,61,206,42,204,97,212,39,246,82,135,7,20,228,201,49,51,249,143,232,203,126,245,253,67,212,35,110,123,185,41,251,190,148,189,
  49. 94,218,185,190,21,127,195,175,252,185,205,147,39,247,132,240,32,209,238,119,252,234,94,220,230,203,67,31,197,205,27,227,172,244,160,215,101,104,57,55,149,239,190,211,230,43,151,249,114,225,241,98,36,63,70,190,167,132,223,185,188,69,81,95,9,226,111,149,
  50. 153,133,222,56,209,171,142,61,69,120,170,160,104,160,150,246,100,118,236,41,192,83,57,158,38,203,167,66,212,187,16,107,157,109,142,115,68,81,47,86,16,122,133,89,132,114,249,84,102,58,96,75,32,190,187,205,121,230,231,168,194,45,158,241,158,74,237,183,
  51. 123,161,69,113,227,185,112,223,24,104,33,156,77,182,111,179,252,220,130,243,190,10,117,70,61,242,60,54,11,105,194,162,89,52,153,137,27,161,237,51,209,243,54,209,39,7,246,175,207,65,162,70,23,90,245,26,182,103,72,247,228,99,242,78,158,208,51,7,227,233,
  52. 204,40,166,150,12,167,203,91,92,150,145,37,53,59,16,167,54,103,182,49,207,40,36,47,247,78,156,176,116,46,121,29,91,61,131,152,135,108,103,139,211,116,120,199,120,165,180,3,151,210,151,77,225,105,194,187,197,168,84,239,247,80,245,157,57,102,245,7,224,
  53. 125,112,12,188,4,196,225,97,152,242,61,96,228,103,251,57,244,15,61,159,248,163,210,197,93,178,8,251,241,18,82,247,23,110,84,223,202,166,124,133,213,221,204,248,244,59,88,205,62,70,58,186,224,221,47,160,124,166,213,231,149,113,214,148,145,15,239,125,1,
  54. 237,99,129,213,84,105,228,98,207,59,100,188,155,27,80,49,54,186,174,143,42,151,184,165,63,39,203,44,77,166,5,22,163,76,182,244,193,100,90,75,42,237,236,84,154,75,222,254,16,135,117,218,160,179,77,70,6,81,167,67,239,123,43,160,246,76,235,66,111,90,124,
  55. 49,224,139,194,18,13,52,227,118,84,253,215,145,241,244,235,186,196,123,113,59,198,148,171,251,32,126,226,1,21,251,189,158,188,212,158,185,60,144,220,51,133,178,79,73,251,213,218,190,206,51,70,182,207,245,222,187,54,160,222,61,109,207,114,217,87,25,235,
  56. 80,159,151,170,63,53,116,59,55,4,212,57,146,43,203,169,55,211,175,164,217,156,58,126,127,245,12,99,91,161,199,150,204,255,173,51,228,95,153,154,11,213,143,123,79,209,143,7,78,97,123,36,205,102,234,182,30,15,168,239,11,188,76,124,163,208,17,224,164,164,
  57. 65,27,103,32,238,29,219,24,112,209,198,128,83,91,51,225,199,88,73,207,198,128,137,244,12,236,199,177,232,79,21,249,88,190,30,175,88,147,95,5,212,89,125,234,254,183,45,46,162,232,218,86,50,207,175,62,46,124,195,144,254,247,202,105,203,204,92,246,217,103,
  58. 114,220,11,23,144,25,20,101,220,104,71,156,213,191,11,168,239,57,218,182,231,99,157,196,41,229,198,73,55,142,90,175,68,20,241,228,98,215,187,177,251,189,66,154,182,167,64,72,135,141,53,204,164,44,167,107,251,96,70,147,246,17,177,166,110,180,37,124,244,
  59. 163,128,250,174,195,235,105,141,161,39,226,140,101,56,99,153,58,233,166,139,87,62,18,41,54,206,45,85,95,150,144,78,215,86,182,99,208,217,130,249,173,254,67,36,48,150,118,102,226,228,59,98,123,206,194,8,171,197,69,143,171,113,38,191,191,17,178,64,147,
  60. 173,207,218,49,51,212,123,159,151,90,175,66,219,78,217,182,115,62,51,208,242,252,204,76,180,137,158,227,4,247,86,213,87,186,40,178,112,28,221,242,32,90,121,223,246,184,97,207,102,243,152,184,89,40,221,246,13,11,191,117,136,154,68,31,179,68,31,175,100,
  61. 123,84,31,189,158,234,23,212,220,139,245,154,57,67,125,239,48,122,238,213,136,133,77,140,213,73,110,30,93,187,10,171,134,178,127,38,189,163,137,22,205,24,241,169,76,29,59,86,207,80,107,25,217,80,74,109,131,233,181,206,67,155,202,135,99,240,97,81,38,79,
  62. 175,229,38,36,151,161,162,214,103,145,219,16,35,103,134,156,117,150,199,108,79,14,234,119,103,138,181,203,165,44,215,175,110,252,140,166,177,15,165,215,86,191,215,250,156,23,210,246,229,227,140,21,235,44,98,129,88,151,2,33,157,174,103,7,51,214,136,17,
  63. 231,87,191,124,230,156,107,85,206,255,60,115,206,243,145,211,246,136,211,210,157,229,205,159,91,90,67,222,202,9,101,179,113,18,44,193,253,216,59,110,246,131,149,36,106,17,117,124,79,212,225,43,20,146,121,29,75,29,217,142,171,214,61,62,198,246,141,81,
  64. 150,162,165,206,108,231,85,61,143,23,37,235,61,228,118,179,234,215,208,143,171,113,83,199,165,254,135,55,190,238,102,25,243,221,37,244,247,142,96,42,245,124,150,222,159,127,166,39,162,166,234,95,255,227,61,88,163,123,48,233,255,221,131,53,178,7,88,102,
  65. 166,190,29,20,190,37,226,144,95,75,17,191,196,187,91,92,250,30,151,119,150,23,102,168,239,50,209,71,156,251,46,202,230,227,140,255,37,111,225,132,165,56,247,29,157,78,156,251,242,12,143,83,189,41,238,145,46,244,59,7,251,31,124,226,245,78,168,194,169,
  66. 111,136,83,63,3,39,123,139,201,13,113,218,111,229,213,239,230,240,234,163,224,119,224,136,240,247,124,244,173,84,238,93,68,61,62,189,168,166,196,168,174,158,50,189,174,38,45,222,26,245,35,123,195,208,214,172,122,117,7,158,199,93,36,102,196,70,142,92,
  67. 242,46,172,254,88,140,79,197,228,194,122,21,7,196,29,74,220,118,199,241,159,202,59,84,37,90,171,192,251,219,60,68,15,219,115,9,118,168,155,45,96,5,152,109,59,48,137,2,24,241,185,50,191,29,152,72,30,179,109,70,1,110,182,117,178,254,100,138,151,219,129,
  68. 9,228,225,42,205,47,230,247,125,146,191,239,18,63,201,239,92,197,123,206,116,216,102,37,191,60,213,63,11,79,120,94,115,194,179,40,95,72,234,236,205,71,239,152,182,9,124,90,102,232,116,175,62,103,199,105,123,133,150,92,227,211,243,53,141,230,74,123,173,
  69. 182,215,34,58,43,201,100,60,101,250,159,131,70,206,116,174,125,35,121,150,155,41,157,105,187,43,245,93,50,199,76,179,84,126,33,115,82,101,132,116,234,52,39,242,113,109,115,105,153,169,101,242,187,232,92,217,43,210,247,11,49,198,153,122,44,62,105,159,
  70. 169,125,120,102,170,215,170,252,44,45,103,235,114,201,126,10,153,163,219,23,122,94,42,61,47,109,76,57,169,177,22,167,250,161,234,246,232,246,124,169,156,106,92,62,157,155,145,122,223,102,213,132,247,41,103,99,200,14,37,206,38,126,118,3,21,45,137,244,
  71. 71,35,182,101,39,214,88,86,108,125,200,218,86,183,57,56,24,36,182,156,248,242,38,98,77,196,155,166,2,168,43,136,175,104,166,242,21,3,93,214,162,174,46,43,30,15,117,134,194,161,196,240,170,72,183,181,38,22,25,12,117,91,49,42,94,105,13,119,70,130,177,238,
  72. 165,161,120,127,40,30,111,14,197,19,150,141,4,214,76,188,25,181,53,163,154,230,102,50,154,241,128,143,21,226,163,153,138,154,131,118,119,44,18,234,246,7,163,81,255,162,174,68,104,16,53,55,208,172,209,246,104,52,28,234,10,38,66,17,123,98,50,79,115,168,
  73. 199,234,26,238,10,91,75,130,225,112,103,176,107,75,188,129,198,158,174,84,122,82,87,196,70,207,18,254,37,66,14,37,210,147,122,99,193,104,95,168,43,238,95,18,180,7,131,168,112,252,41,146,34,225,72,108,121,40,156,176,98,167,79,111,9,38,98,161,161,6,154,
  74. 250,55,211,71,85,85,114,114,214,53,193,144,141,254,21,159,156,178,214,234,66,66,65,42,33,18,247,47,30,176,187,195,86,3,21,166,27,155,22,135,236,110,81,251,72,29,131,88,106,63,22,107,217,160,37,42,31,55,58,161,37,34,166,75,167,77,29,157,38,156,100,226,
  75. 106,123,121,164,107,32,190,164,47,104,247,90,201,69,78,239,74,42,107,250,144,82,198,115,99,145,129,104,3,205,57,57,165,45,102,89,171,59,227,86,108,208,138,161,149,115,195,145,206,96,184,57,56,28,25,72,140,52,83,241,183,203,53,208,140,209,25,130,233,254,
  76. 234,31,229,189,45,65,59,216,43,138,212,255,221,69,132,195,55,217,61,145,147,250,127,134,50,201,77,210,64,117,163,203,133,236,232,64,162,223,74,244,69,186,253,139,131,113,84,142,103,248,165,141,229,149,94,59,233,244,249,151,117,135,18,145,152,234,78,205,
  77. 233,179,157,84,101,237,25,242,182,72,61,53,59,231,52,119,69,250,253,177,254,120,216,191,25,1,192,127,82,216,152,248,55,227,66,3,45,63,99,5,167,137,28,19,71,175,236,252,127,182,158,6,170,60,83,209,6,170,106,238,14,134,7,67,91,252,65,219,142,36,100,204,
  78. 240,47,179,187,194,145,120,200,238,93,18,14,198,101,48,56,57,79,19,38,54,166,211,43,79,145,222,98,245,119,234,12,22,178,148,159,34,75,107,168,215,14,38,6,98,150,216,48,34,6,251,195,216,91,126,236,176,88,171,181,117,192,178,187,144,146,159,158,162,154,
  79. 171,74,51,53,133,195,86,111,48,172,150,97,217,80,151,21,85,139,61,241,20,121,98,189,3,253,24,123,90,174,130,244,92,8,138,189,106,210,70,140,171,34,173,3,93,125,202,51,210,202,121,211,178,172,238,220,44,99,82,121,154,173,213,234,26,136,193,33,78,83,164,
  80. 21,49,208,238,21,30,57,98,139,89,61,97,212,131,110,12,70,84,232,110,11,198,122,173,244,222,142,59,69,118,213,181,6,26,163,210,6,18,161,176,127,81,44,22,28,22,78,208,64,121,105,102,97,33,207,9,134,6,50,219,54,174,89,70,217,233,62,71,108,61,241,245,77,
  81. 228,88,223,132,31,168,43,200,185,126,69,211,242,229,120,155,135,20,9,43,68,2,30,196,193,182,126,69,59,242,8,69,28,110,235,165,169,185,29,169,205,237,56,250,214,183,163,112,187,172,136,181,147,209,46,202,225,163,89,168,205,228,104,95,33,116,19,2,199,101,
  82. 187,176,226,152,116,182,55,75,179,67,72,216,59,112,54,119,52,145,183,227,100,103,40,232,56,197,90,184,85,92,154,24,8,4,82,250,140,52,189,62,77,159,153,166,207,74,211,103,167,233,115,210,244,185,105,250,60,232,89,74,95,30,14,246,198,41,103,84,64,164,194,
  83. 224,41,2,47,57,131,50,34,137,146,66,54,7,59,173,48,101,4,245,241,78,99,131,221,221,167,62,6,40,51,168,125,56,78,172,147,242,197,225,191,120,32,145,136,216,107,98,104,198,234,38,103,103,4,143,253,144,242,80,36,103,151,60,207,201,213,37,143,173,110,114,
  84. 224,222,16,140,81,86,151,8,85,17,156,178,139,18,226,33,117,50,83,174,124,104,139,5,237,120,79,36,214,79,57,226,214,128,227,56,46,115,163,34,117,121,64,69,145,1,60,151,118,197,172,96,226,228,48,40,194,51,153,221,161,158,30,98,22,57,44,113,174,146,175,
  85. 7,135,242,41,179,198,23,15,183,137,90,51,69,14,121,206,146,163,71,138,236,158,145,83,183,155,178,228,147,136,92,77,221,84,138,237,49,170,182,229,105,137,101,39,38,142,186,180,101,202,84,185,10,121,41,181,37,24,223,130,54,198,8,195,200,13,74,223,150,40,
  86. 7,102,17,154,176,78,86,44,78,25,226,81,184,32,185,133,166,51,101,139,29,43,198,218,22,234,183,100,43,231,89,161,222,190,4,21,64,149,167,76,122,31,133,177,89,239,246,213,118,43,166,210,178,101,21,216,213,193,86,68,73,85,133,218,227,178,163,114,17,16,86,
  87. 229,220,103,143,24,80,153,11,79,107,131,219,54,36,149,141,148,37,148,72,36,33,90,35,15,30,90,135,225,71,253,173,216,227,161,46,139,114,97,89,103,135,132,39,136,113,201,222,156,120,175,144,163,94,31,74,57,180,40,115,1,150,40,178,173,45,178,5,157,45,75,
  88. 61,203,76,97,11,71,80,52,28,28,94,30,11,98,252,38,82,55,200,207,141,196,250,168,4,139,8,167,28,181,42,231,69,68,43,121,58,37,26,93,19,28,16,126,236,73,25,214,90,113,120,124,202,178,56,229,242,148,163,44,56,252,150,70,182,97,55,165,30,215,69,169,48,245,
  89. 32,15,198,243,66,221,221,232,173,110,166,37,130,54,100,153,81,134,88,176,55,89,167,52,160,26,93,167,188,142,82,129,126,176,98,98,99,104,239,201,232,11,198,149,191,22,247,193,179,90,35,61,122,153,99,145,126,53,49,200,130,210,210,187,205,190,8,66,48,11,
  90. 145,27,222,177,90,70,245,56,25,161,254,126,202,19,239,39,161,96,120,73,48,26,111,193,130,80,142,54,180,90,225,101,118,119,42,29,143,240,139,24,54,138,188,190,180,13,71,45,202,150,234,197,234,42,67,25,104,108,125,48,60,128,189,31,194,81,178,197,66,99,
  91. 241,38,59,158,8,226,56,69,106,124,117,52,136,179,149,198,134,226,109,17,156,109,203,134,162,216,239,210,5,151,217,65,172,96,55,234,142,235,213,36,215,22,107,120,137,232,79,241,150,211,188,229,228,36,19,90,251,196,140,58,194,50,154,229,192,7,172,152,232,
  92. 222,42,220,55,200,12,91,61,9,114,134,45,187,55,209,71,78,221,85,102,147,105,11,63,113,217,214,182,85,66,201,176,147,161,35,219,78,223,174,206,72,167,136,65,100,70,194,221,125,242,115,27,229,71,236,228,27,209,18,25,131,176,159,70,76,75,173,120,34,22,25,
  93. 22,142,51,98,212,206,149,86,50,233,93,165,35,166,214,224,160,149,156,47,181,7,211,242,203,201,31,93,69,107,34,18,141,194,84,140,80,33,251,113,194,197,19,157,183,225,91,219,40,39,146,254,6,65,185,145,81,49,158,178,35,182,220,12,50,124,80,102,196,78,58,
  94. 118,142,84,91,6,194,137,80,84,44,137,124,132,115,102,136,163,67,22,69,142,214,208,37,86,50,72,162,38,181,180,178,38,103,68,45,184,75,201,139,81,110,0,81,63,129,24,230,136,74,199,118,71,131,49,228,148,97,34,39,58,202,189,29,81,25,245,203,163,145,232,64,
  95. 248,180,113,158,197,200,21,83,239,164,84,21,179,122,133,111,196,78,255,186,74,101,49,171,31,67,85,195,95,109,159,112,200,57,98,50,98,26,113,43,65,185,113,17,91,83,47,139,148,141,103,57,137,194,83,169,56,253,169,73,13,90,238,30,81,44,237,78,47,139,53,
  96. 39,61,146,74,240,116,202,183,57,26,19,79,6,201,117,161,180,168,87,122,74,179,184,76,7,113,122,198,85,216,148,14,156,19,31,21,46,221,201,199,176,234,211,5,161,112,120,85,36,33,221,33,59,142,13,147,12,80,40,136,167,84,244,64,102,225,104,170,95,184,42,34,
  97. 25,94,54,242,88,18,87,189,105,26,105,75,143,212,148,199,144,153,232,11,197,201,41,62,39,6,180,156,1,171,56,148,12,212,4,85,76,68,198,64,162,103,158,140,253,108,144,28,131,50,106,184,164,88,221,67,166,120,75,162,60,241,153,238,92,153,194,208,22,89,23,
  98. 183,200,51,120,210,105,49,24,138,37,6,130,97,125,190,185,7,71,166,130,109,35,54,68,124,40,0,102,128,122,48,19,204,34,54,76,223,52,57,237,229,174,220,246,90,186,199,100,183,112,87,57,207,122,150,15,149,111,54,232,151,172,228,141,149,244,144,201,175,229,
  99. 176,231,210,163,38,187,142,185,202,159,228,151,148,191,111,208,245,172,166,246,38,7,209,115,166,113,11,143,111,115,229,62,90,65,191,229,140,80,85,35,253,142,147,107,122,135,193,223,103,57,215,26,236,93,86,80,55,244,145,65,215,48,190,185,145,229,231,135,
  100. 26,121,188,220,65,141,44,203,137,242,92,117,128,207,217,200,87,110,171,165,95,112,118,187,104,237,68,121,8,85,230,222,79,175,40,209,104,92,205,126,207,126,204,92,211,249,179,212,192,63,101,219,248,51,108,219,16,127,227,210,215,118,49,238,112,47,170,109,
  101. 172,107,108,60,187,195,160,237,204,125,153,193,174,100,179,27,239,170,52,140,95,176,0,43,30,19,24,111,240,167,24,103,249,197,14,206,207,71,87,28,204,97,56,221,124,218,1,135,219,73,78,230,228,78,163,166,134,15,78,119,240,26,30,159,78,115,85,23,230,242,
  102. 219,249,29,82,49,133,242,85,254,181,209,214,148,226,72,38,239,23,143,215,137,46,127,161,140,6,33,86,210,97,131,239,227,119,10,251,235,38,12,180,75,76,25,189,100,136,207,47,152,124,224,82,200,29,38,27,128,120,215,16,2,37,111,150,207,215,149,209,167,134,
  103. 202,176,91,101,56,46,51,208,141,6,59,138,133,89,185,178,182,125,101,123,29,125,158,93,38,75,221,107,240,27,249,143,24,10,150,214,210,219,140,237,130,186,139,21,229,249,104,15,231,79,136,199,242,157,124,76,57,239,47,231,121,13,117,43,45,62,176,226,66,
  104. 62,188,130,30,228,198,19,108,135,76,231,249,215,240,88,249,222,142,205,187,12,199,110,206,253,214,57,116,175,46,155,187,211,87,182,151,238,54,28,151,63,205,190,196,63,100,151,160,35,251,13,243,54,126,55,123,129,253,15,210,23,236,108,167,91,84,171,59,
  105. 249,19,84,206,31,252,124,249,74,35,51,206,155,13,215,245,220,224,143,210,70,190,112,58,43,200,11,40,60,205,70,214,51,140,47,104,52,178,143,177,57,11,24,51,220,15,50,94,203,202,114,206,113,184,29,217,51,28,89,155,157,238,58,86,80,196,47,109,104,116,102,
  106. 47,96,229,99,132,125,180,145,47,103,229,185,244,136,193,110,197,12,251,12,182,139,7,152,183,136,103,79,199,40,43,12,218,201,106,199,59,72,42,211,38,56,232,245,64,13,253,196,96,207,161,139,244,170,193,134,92,185,161,50,58,206,216,13,40,252,152,65,7,89,
  107. 121,221,230,149,67,155,198,238,36,94,201,110,228,37,62,94,197,35,166,247,25,86,156,195,39,194,80,230,42,102,197,11,139,51,139,151,22,243,226,154,98,83,229,170,144,185,224,143,197,231,166,242,231,242,9,34,63,43,25,175,20,94,82,94,82,65,156,153,238,221,
  108. 62,230,157,124,229,118,243,80,217,20,118,188,140,177,67,229,140,125,0,142,141,71,50,203,230,108,183,111,218,246,237,230,193,138,233,236,181,10,50,156,148,43,74,48,111,45,202,28,168,100,187,124,207,139,143,163,226,99,71,21,227,183,131,199,170,200,89,82,
  109. 154,239,133,135,123,213,191,153,200,124,180,10,89,30,152,140,143,103,196,199,17,241,177,99,10,62,246,139,143,131,83,204,171,56,49,32,164,75,235,127,47,133,192,13,206,98,135,166,96,201,171,25,59,80,109,176,7,170,139,216,51,208,143,128,47,78,101,108,63,
  110. 184,31,28,6,123,106,24,251,54,56,8,158,1,7,166,97,232,224,139,211,25,123,13,188,92,203,216,243,117,204,220,237,103,230,1,63,210,252,14,182,127,22,99,247,204,230,236,167,224,240,108,79,218,239,7,146,50,249,119,57,226,251,234,228,223,230,136,239,177,147,
  111. 127,159,147,252,93,169,248,27,29,241,29,118,242,239,116,156,52,242,183,58,134,71,127,191,157,139,58,125,234,247,66,27,160,59,125,42,143,248,255,103,204,163,236,226,255,156,113,159,106,87,252,109,143,161,243,139,255,247,101,250,212,239,37,166,214,171,
  112. 95,84,136,178,242,255,173,121,84,95,197,223,17,253,31,67,245,215,66,128,52,0,0,0,0 };
  113. //==============================================================================
  114. #if JUCE_PUSH_NOTIFICATIONS && JUCE_MODULE_AVAILABLE_juce_gui_extra
  115. extern bool juce_handleNotificationIntent (void*);
  116. extern void juce_firebaseDeviceNotificationsTokenRefreshed (void*);
  117. extern void juce_firebaseRemoteNotificationReceived (void*);
  118. extern void juce_firebaseRemoteMessagesDeleted();
  119. extern void juce_firebaseRemoteMessageSent(void*);
  120. extern void juce_firebaseRemoteMessageSendError (void*, void*);
  121. #endif
  122. //==============================================================================
  123. #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
  124. METHOD (create, "<init>", "(II)V")
  125. DECLARE_JNI_CLASS (AndroidLayoutParams, "android/view/ViewGroup$LayoutParams")
  126. #undef JNI_CLASS_MEMBERS
  127. #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
  128. METHOD (addView, "addView", "(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V") \
  129. METHOD (removeView, "removeView", "(Landroid/view/View;)V") \
  130. METHOD (updateViewLayout, "updateViewLayout", "(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V")
  131. DECLARE_JNI_CLASS (AndroidViewManager, "android/view/ViewManager")
  132. #undef JNI_CLASS_MEMBERS
  133. #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
  134. METHOD (create, "<init>", "(IIIIIII)V") \
  135. FIELD (gravity, "gravity", "I") \
  136. FIELD (windowAnimations, "windowAnimations", "I")
  137. DECLARE_JNI_CLASS (AndroidWindowManagerLayoutParams, "android/view/WindowManager$LayoutParams")
  138. #undef JNI_CLASS_MEMBERS
  139. #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
  140. METHOD (getDisplayCutout, "getDisplayCutout", "()Landroid/view/DisplayCutout;")
  141. DECLARE_JNI_CLASS_WITH_MIN_SDK (AndroidWindowInsets, "android/view/WindowInsets", 28)
  142. #undef JNI_CLASS_MEMBERS
  143. #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
  144. METHOD (getSafeInsetBottom, "getSafeInsetBottom", "()I") \
  145. METHOD (getSafeInsetLeft, "getSafeInsetLeft", "()I") \
  146. METHOD (getSafeInsetRight, "getSafeInsetRight", "()I") \
  147. METHOD (getSafeInsetTop, "getSafeInsetTop", "()I")
  148. DECLARE_JNI_CLASS_WITH_MIN_SDK (AndroidDisplayCutout, "android/view/DisplayCutout", 28)
  149. #undef JNI_CLASS_MEMBERS
  150. //==============================================================================
  151. namespace
  152. {
  153. enum
  154. {
  155. SYSTEM_UI_FLAG_VISIBLE = 0,
  156. SYSTEM_UI_FLAG_LOW_PROFILE = 1,
  157. SYSTEM_UI_FLAG_HIDE_NAVIGATION = 2,
  158. SYSTEM_UI_FLAG_FULLSCREEN = 4,
  159. SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION = 512,
  160. SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN = 1024,
  161. SYSTEM_UI_FLAG_IMMERSIVE = 2048,
  162. SYSTEM_UI_FLAG_IMMERSIVE_STICKY = 4096
  163. };
  164. constexpr int fullScreenFlags = SYSTEM_UI_FLAG_HIDE_NAVIGATION | SYSTEM_UI_FLAG_FULLSCREEN | SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
  165. constexpr int FLAG_NOT_FOCUSABLE = 0x8;
  166. }
  167. //==============================================================================
  168. static bool supportsDisplayCutout()
  169. {
  170. return getAndroidSDKVersion() >= 28;
  171. }
  172. static BorderSize<int> androidDisplayCutoutToBorderSize (LocalRef<jobject> displayCutout, double displayScale)
  173. {
  174. if (displayCutout.get() == nullptr)
  175. return {};
  176. auto* env = getEnv();
  177. auto getInset = [&] (jmethodID methodID)
  178. {
  179. return roundToInt (env->CallIntMethod (displayCutout.get(), methodID) / displayScale);
  180. };
  181. return { getInset (AndroidDisplayCutout.getSafeInsetTop),
  182. getInset (AndroidDisplayCutout.getSafeInsetLeft),
  183. getInset (AndroidDisplayCutout.getSafeInsetBottom),
  184. getInset (AndroidDisplayCutout.getSafeInsetRight) };
  185. }
  186. /* The usage of the KeyPress class relies on its keyCode member having the standard ASCII values
  187. represent ASCII keycodes. However in the native Android keycodes the values for special keys
  188. e.g. RETURN, F1-F12 overlap with the ASCII range. Hence we need to translate them.
  189. */
  190. static constexpr int translateAndroidKeyCode (int keyCode) noexcept
  191. {
  192. switch (keyCode)
  193. {
  194. case 7: return '0';
  195. case 8: return '1';
  196. case 9: return '2';
  197. case 10: return '3';
  198. case 11: return '4';
  199. case 12: return '5';
  200. case 13: return '6';
  201. case 14: return '7';
  202. case 15: return '8';
  203. case 16: return '9';
  204. case 17: return '*';
  205. case 18: return '#';
  206. case 19: return KeyPress::upKey; // KEYCODE_DPAD_UP
  207. case 20: return KeyPress::downKey; // KEYCODE_DPAD_DOWN
  208. case 21: return KeyPress::leftKey; // KEYCODE_DPAD_LEFT
  209. case 22: return KeyPress::rightKey; // KEYCODE_DPAD_RIGHT
  210. case 29: return 'A';
  211. case 30: return 'B';
  212. case 31: return 'C';
  213. case 32: return 'D';
  214. case 33: return 'E';
  215. case 34: return 'F';
  216. case 35: return 'G';
  217. case 36: return 'H';
  218. case 37: return 'I';
  219. case 38: return 'J';
  220. case 39: return 'K';
  221. case 40: return 'L';
  222. case 41: return 'M';
  223. case 42: return 'N';
  224. case 43: return 'O';
  225. case 44: return 'P';
  226. case 45: return 'Q';
  227. case 46: return 'R';
  228. case 47: return 'S';
  229. case 48: return 'T';
  230. case 49: return 'U';
  231. case 50: return 'V';
  232. case 51: return 'W';
  233. case 52: return 'X';
  234. case 53: return 'Y';
  235. case 54: return 'Z';
  236. case 55: return ',';
  237. case 56: return '.';
  238. case 61: return KeyPress::tabKey; // KEYCODE_TAB
  239. case 62: return KeyPress::spaceKey; // KEYCODE_SPACE
  240. case 66: return KeyPress::returnKey; // KEYCODE_ENTER
  241. case 67: return KeyPress::backspaceKey; // KEYCODE_DEL
  242. case 68: return '`';
  243. case 69: return '-';
  244. case 70: return '=';
  245. case 71: return '[';
  246. case 72: return ']';
  247. case 73: return '\\';
  248. case 74: return ';';
  249. case 75: return '\'';
  250. case 76: return '/';
  251. case 77: return '@';
  252. case 81: return '+';
  253. case 85: return KeyPress::playKey; // KEYCODE_MEDIA_PLAY_PAUSE
  254. case 86: return KeyPress::stopKey; // KEYCODE_MEDIA_STOP
  255. case 87: return KeyPress::fastForwardKey; // KEYCODE_MEDIA_NEXT
  256. case 88: return KeyPress::rewindKey; // KEYCODE_MEDIA_PREVIOUS
  257. case 92: return KeyPress::pageUpKey; // KEYCODE_PAGE_UP
  258. case 93: return KeyPress::pageDownKey; // KEYCODE_PAGE_DOWN
  259. case 111: return KeyPress::escapeKey; // KEYCODE_ESCAPE
  260. case 112: return KeyPress::deleteKey; // KEYCODE_FORWARD_DEL
  261. case 122: return KeyPress::homeKey; // KEYCODE_MOVE_HOME
  262. case 123: return KeyPress::endKey; // KEYCODE_MOVE_END
  263. case 124: return KeyPress::insertKey; // KEYCODE_INSERT
  264. case 131: return KeyPress::F1Key; // KEYCODE_F1
  265. case 132: return KeyPress::F2Key; // KEYCODE_F2
  266. case 133: return KeyPress::F3Key; // KEYCODE_F3
  267. case 134: return KeyPress::F4Key; // KEYCODE_F4
  268. case 135: return KeyPress::F5Key; // KEYCODE_F5
  269. case 136: return KeyPress::F6Key; // KEYCODE_F6
  270. case 137: return KeyPress::F7Key; // KEYCODE_F7
  271. case 138: return KeyPress::F8Key; // KEYCODE_F8
  272. case 139: return KeyPress::F9Key; // KEYCODE_F9
  273. case 140: return KeyPress::F10Key; // KEYCODE_F10
  274. case 141: return KeyPress::F11Key; // KEYCODE_F11
  275. case 142: return KeyPress::F12Key; // KEYCODE_F12
  276. case 144: return '0';
  277. case 145: return '1';
  278. case 146: return '2';
  279. case 147: return '3';
  280. case 148: return '4';
  281. case 149: return '5';
  282. case 150: return '6';
  283. case 151: return '7';
  284. case 152: return '8';
  285. case 153: return '9';
  286. case 154: return '/';
  287. case 155: return '*';
  288. case 156: return '-';
  289. case 157: return '+';
  290. case 158: return '.';
  291. case 159: return ',';
  292. case 161: return '=';
  293. case 162: return '(';
  294. case 163: return ')';
  295. default: return 0;
  296. }
  297. }
  298. static constexpr int translateAndroidKeyboardFlags (int javaFlags) noexcept
  299. {
  300. constexpr int metaShiftOn = 0x1;
  301. constexpr int metaAltOn = 0x02;
  302. constexpr int metaCtrlOn = 0x1000;
  303. int flags = 0;
  304. if ((javaFlags & metaShiftOn) != 0) flags |= ModifierKeys::shiftModifier;
  305. if ((javaFlags & metaAltOn) != 0) flags |= ModifierKeys::altModifier;
  306. if ((javaFlags & metaCtrlOn) != 0) flags |= ModifierKeys::ctrlModifier;
  307. return flags;
  308. }
  309. //==============================================================================
  310. class AndroidComponentPeer : public ComponentPeer,
  311. private Timer
  312. {
  313. public:
  314. AndroidComponentPeer (Component& comp, int windowStyleFlags, void* nativeViewHandle)
  315. : ComponentPeer (comp, windowStyleFlags)
  316. {
  317. auto* env = getEnv();
  318. // NB: must not put this in the initialiser list, as it invokes a callback,
  319. // which will fail if the peer is only half-constructed.
  320. view = GlobalRef (LocalRef<jobject> (env->NewObject (ComponentPeerView, ComponentPeerView.create,
  321. getAppContext().get(), (jboolean) component.isOpaque(),
  322. (jlong) this)));
  323. if (nativeViewHandle != nullptr)
  324. {
  325. viewGroupIsWindow = false;
  326. // we don't know if the user is holding on to a local ref to this, so
  327. // explicitly create a new one
  328. auto nativeView = LocalRef<jobject> (env->NewLocalRef (static_cast<jobject> (nativeViewHandle)));
  329. if (env->IsInstanceOf (nativeView.get(), AndroidActivity))
  330. {
  331. viewGroup = GlobalRef (nativeView);
  332. env->CallVoidMethod (viewGroup.get(), AndroidActivity.setContentView, view.get());
  333. }
  334. else if (env->IsInstanceOf (nativeView.get(), AndroidViewGroup))
  335. {
  336. viewGroup = GlobalRef (nativeView);
  337. LocalRef<jobject> layoutParams (env->NewObject (AndroidLayoutParams, AndroidLayoutParams.create, -2, -2));
  338. env->CallVoidMethod (view.get(), AndroidView.setLayoutParams, layoutParams.get());
  339. env->CallVoidMethod ((jobject) viewGroup.get(), AndroidViewGroup.addView, view.get());
  340. }
  341. else
  342. {
  343. // the native handle you passed as a second argument to Component::addToDesktop must
  344. // either be an Activity or a ViewGroup
  345. jassertfalse;
  346. }
  347. }
  348. else
  349. {
  350. viewGroupIsWindow = true;
  351. LocalRef<jobject> viewLayoutParams (env->NewObject (AndroidLayoutParams, AndroidLayoutParams.create, -2, -2));
  352. env->CallVoidMethod (view.get(), AndroidView.setLayoutParams, viewLayoutParams.get());
  353. auto physicalBounds = (comp.getBoundsInParent().toFloat() * scale).toNearestInt();
  354. view.callVoidMethod (AndroidView.layout,
  355. physicalBounds.getX(), physicalBounds.getY(), physicalBounds.getRight(), physicalBounds.getBottom());
  356. LocalRef<jobject> windowLayoutParams (env->NewObject (AndroidWindowManagerLayoutParams, AndroidWindowManagerLayoutParams.create,
  357. physicalBounds.getWidth(), physicalBounds.getHeight(),
  358. physicalBounds.getX(), physicalBounds.getY(),
  359. TYPE_APPLICATION, FLAG_NOT_TOUCH_MODAL | FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_NO_LIMITS | FLAG_NOT_FOCUSABLE,
  360. component.isOpaque() ? PIXEL_FORMAT_OPAQUE : PIXEL_FORMAT_TRANSPARENT));
  361. env->SetIntField (windowLayoutParams.get(), AndroidWindowManagerLayoutParams.gravity, GRAVITY_LEFT | GRAVITY_TOP);
  362. env->SetIntField (windowLayoutParams.get(), AndroidWindowManagerLayoutParams.windowAnimations, 0x01030000 /* android.R.style.Animation */);
  363. if (supportsDisplayCutout())
  364. {
  365. jfieldID layoutInDisplayCutoutModeFieldId = env->GetFieldID (AndroidWindowManagerLayoutParams,
  366. "layoutInDisplayCutoutMode",
  367. "I");
  368. if (layoutInDisplayCutoutModeFieldId != nullptr)
  369. env->SetIntField (windowLayoutParams.get(),
  370. layoutInDisplayCutoutModeFieldId,
  371. LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS);
  372. }
  373. if (Desktop::getInstance().getKioskModeComponent() != nullptr)
  374. setNavBarsHidden (true);
  375. LocalRef<jobject> activity (getCurrentActivity());
  376. if (activity == nullptr)
  377. activity = getMainActivity();
  378. viewGroup = GlobalRef (LocalRef<jobject> (env->CallObjectMethod (activity.get(), AndroidContext.getSystemService, javaString ("window").get())));
  379. env->CallVoidMethod (viewGroup.get(), AndroidViewManager.addView, view.get(), windowLayoutParams.get());
  380. }
  381. if (supportsDisplayCutout())
  382. {
  383. jmethodID setOnApplyWindowInsetsListenerMethodId = env->GetMethodID (AndroidView,
  384. "setOnApplyWindowInsetsListener",
  385. "(Landroid/view/View$OnApplyWindowInsetsListener;)V");
  386. if (setOnApplyWindowInsetsListenerMethodId != nullptr)
  387. env->CallVoidMethod (view.get(), setOnApplyWindowInsetsListenerMethodId,
  388. CreateJavaInterface (new ViewWindowInsetsListener,
  389. "android/view/View$OnApplyWindowInsetsListener").get());
  390. }
  391. if (isFocused())
  392. handleFocusGain();
  393. }
  394. ~AndroidComponentPeer() override
  395. {
  396. stopTimer();
  397. auto* env = getEnv();
  398. env->CallVoidMethod (view, ComponentPeerView.clear);
  399. frontWindow = nullptr;
  400. GlobalRef localView (view);
  401. GlobalRef localViewGroup (viewGroup);
  402. callOnMessageThread ([env, localView, localViewGroup]
  403. {
  404. if (env->IsInstanceOf (localViewGroup.get(), AndroidActivity))
  405. env->CallVoidMethod (localViewGroup.get(), AndroidActivity.setContentView, nullptr);
  406. else
  407. env->CallVoidMethod (localViewGroup.get(), AndroidViewManager.removeView, localView.get());
  408. });
  409. }
  410. void* getNativeHandle() const override
  411. {
  412. return (void*) view.get();
  413. }
  414. void setVisible (bool shouldBeVisible) override
  415. {
  416. GlobalRef localView (view);
  417. callOnMessageThread ([localView, shouldBeVisible]
  418. {
  419. localView.callVoidMethod (ComponentPeerView.setVisible, shouldBeVisible);
  420. });
  421. }
  422. void setTitle (const String& title) override
  423. {
  424. view.callVoidMethod (ComponentPeerView.setViewName, javaString (title).get());
  425. }
  426. void setBounds (const Rectangle<int>& userRect, bool isNowFullScreen) override
  427. {
  428. auto bounds = (userRect.toFloat() * scale).toNearestInt();
  429. if (MessageManager::getInstance()->isThisTheMessageThread())
  430. {
  431. fullScreen = isNowFullScreen;
  432. view.callVoidMethod (AndroidView.layout,
  433. bounds.getX(), bounds.getY(), bounds.getRight(), bounds.getBottom());
  434. if (viewGroup != nullptr && viewGroupIsWindow)
  435. {
  436. auto* env = getEnv();
  437. LocalRef<jobject> windowLayoutParams (env->NewObject (AndroidWindowManagerLayoutParams, AndroidWindowManagerLayoutParams.create,
  438. bounds.getWidth(), bounds.getHeight(), bounds.getX(), bounds.getY(),
  439. TYPE_APPLICATION, FLAG_NOT_TOUCH_MODAL | FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_NO_LIMITS,
  440. component.isOpaque() ? PIXEL_FORMAT_OPAQUE : PIXEL_FORMAT_TRANSPARENT));
  441. env->SetIntField (windowLayoutParams.get(), AndroidWindowManagerLayoutParams.gravity, GRAVITY_LEFT | GRAVITY_TOP);
  442. env->CallVoidMethod (viewGroup.get(), AndroidViewManager.updateViewLayout, view.get(), windowLayoutParams.get());
  443. }
  444. }
  445. else
  446. {
  447. GlobalRef localView (view);
  448. MessageManager::callAsync ([localView, bounds]
  449. {
  450. localView.callVoidMethod (AndroidView.layout,
  451. bounds.getX(), bounds.getY(), bounds.getRight(), bounds.getBottom());
  452. });
  453. }
  454. }
  455. Rectangle<int> getBounds() const override
  456. {
  457. Rectangle<int> bounds (view.callIntMethod (AndroidView.getLeft),
  458. view.callIntMethod (AndroidView.getTop),
  459. view.callIntMethod (AndroidView.getWidth),
  460. view.callIntMethod (AndroidView.getHeight));
  461. return (bounds.toFloat() / scale).toNearestInt();
  462. }
  463. void handleScreenSizeChange() override
  464. {
  465. ComponentPeer::handleScreenSizeChange();
  466. if (isFullScreen())
  467. setFullScreen (true);
  468. }
  469. Point<int> getScreenPosition() const
  470. {
  471. auto* env = getEnv();
  472. LocalRef<jintArray> position (env->NewIntArray (2));
  473. env->CallVoidMethod (view.get(), AndroidView.getLocationOnScreen, position.get());
  474. jint* const screenPosition = env->GetIntArrayElements (position.get(), nullptr);
  475. Point<int> pos (screenPosition[0], screenPosition[1]);
  476. env->ReleaseIntArrayElements (position.get(), screenPosition, 0);
  477. return pos;
  478. }
  479. Point<float> localToGlobal (Point<float> relativePosition) override
  480. {
  481. return relativePosition + (getScreenPosition().toFloat() / scale);
  482. }
  483. using ComponentPeer::localToGlobal;
  484. Point<float> globalToLocal (Point<float> screenPosition) override
  485. {
  486. return screenPosition - (getScreenPosition().toFloat() / scale);
  487. }
  488. using ComponentPeer::globalToLocal;
  489. void setMinimised (bool /*shouldBeMinimised*/) override
  490. {
  491. // n/a
  492. }
  493. bool isMinimised() const override
  494. {
  495. return false;
  496. }
  497. void setFullScreen (bool shouldBeFullScreen) override
  498. {
  499. if (shouldNavBarsBeHidden (shouldBeFullScreen))
  500. {
  501. if (isTimerRunning())
  502. return;
  503. startTimer (500);
  504. }
  505. else
  506. {
  507. setNavBarsHidden (false);
  508. }
  509. auto newBounds = [&]
  510. {
  511. if (navBarsHidden || shouldBeFullScreen)
  512. if (auto* display = Desktop::getInstance().getDisplays().getPrimaryDisplay())
  513. return navBarsHidden ? display->totalArea
  514. : display->userArea;
  515. return lastNonFullscreenBounds.isEmpty() ? getBounds() : lastNonFullscreenBounds;
  516. }();
  517. if (! newBounds.isEmpty())
  518. setBounds (newBounds, shouldBeFullScreen);
  519. component.repaint();
  520. }
  521. bool isFullScreen() const override
  522. {
  523. return fullScreen;
  524. }
  525. void setIcon (const Image& /*newIcon*/) override
  526. {
  527. // n/a
  528. }
  529. bool contains (Point<int> localPos, bool trueIfInAChildWindow) const override
  530. {
  531. return isPositiveAndBelow (localPos.x, component.getWidth())
  532. && isPositiveAndBelow (localPos.y, component.getHeight())
  533. && ((! trueIfInAChildWindow) || view.callBooleanMethod (ComponentPeerView.containsPoint,
  534. (float) localPos.x * scale,
  535. (float) localPos.y * scale));
  536. }
  537. OptionalBorderSize getFrameSizeIfPresent() const override
  538. {
  539. // TODO
  540. return {};
  541. }
  542. BorderSize<int> getFrameSize() const override
  543. {
  544. // TODO
  545. return {};
  546. }
  547. bool setAlwaysOnTop (bool /*alwaysOnTop*/) override
  548. {
  549. // TODO
  550. return false;
  551. }
  552. void toFront (bool makeActive) override
  553. {
  554. // Avoid calling bringToFront excessively: it's very slow
  555. if (frontWindow != this)
  556. {
  557. view.callVoidMethod (AndroidView.bringToFront);
  558. frontWindow = this;
  559. }
  560. if (makeActive)
  561. grabFocus();
  562. handleBroughtToFront();
  563. }
  564. void toBehind (ComponentPeer*) override
  565. {
  566. // TODO
  567. }
  568. //==============================================================================
  569. void handleMouseDownCallback (int index, Point<float> sysPos, int64 time)
  570. {
  571. lastMousePos = sysPos / scale;
  572. auto pos = globalToLocal (lastMousePos);
  573. // this forces a mouse-enter/up event, in case for some reason we didn't get a mouse-up before.
  574. handleMouseEvent (MouseInputSource::InputSourceType::touch,
  575. pos,
  576. ModifierKeys::currentModifiers.withoutMouseButtons(),
  577. MouseInputSource::defaultPressure,
  578. MouseInputSource::defaultOrientation,
  579. time,
  580. {},
  581. index);
  582. if (isValidPeer (this))
  583. handleMouseDragCallback (index, sysPos, time);
  584. }
  585. void handleMouseDragCallback (int index, Point<float> sysPos, int64 time)
  586. {
  587. lastMousePos = sysPos / scale;
  588. auto pos = globalToLocal (lastMousePos);
  589. jassert (index < 64);
  590. touchesDown = (touchesDown | (1 << (index & 63)));
  591. ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier);
  592. handleMouseEvent (MouseInputSource::InputSourceType::touch,
  593. pos,
  594. ModifierKeys::currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier),
  595. MouseInputSource::defaultPressure,
  596. MouseInputSource::defaultOrientation,
  597. time,
  598. {},
  599. index);
  600. }
  601. void handleMouseUpCallback (int index, Point<float> sysPos, int64 time)
  602. {
  603. lastMousePos = sysPos / scale;
  604. auto pos = globalToLocal (lastMousePos);
  605. jassert (index < 64);
  606. touchesDown = (touchesDown & ~(1 << (index & 63)));
  607. if (touchesDown == 0)
  608. ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withoutMouseButtons();
  609. handleMouseEvent (MouseInputSource::InputSourceType::touch,
  610. pos,
  611. ModifierKeys::currentModifiers.withoutMouseButtons(),
  612. MouseInputSource::defaultPressure,
  613. MouseInputSource::defaultOrientation,
  614. time,
  615. {},
  616. index);
  617. }
  618. void handleAccessibilityHoverCallback (int command, Point<float> sysPos, int64)
  619. {
  620. enum
  621. {
  622. TYPE_VIEW_HOVER_ENTER = 0x00000080,
  623. TYPE_VIEW_HOVER_EXIT = 0x00000100,
  624. ACTION_HOVER_ENTER = 0x00000009,
  625. ACTION_HOVER_MOVE = 0x00000007,
  626. ACTION_HOVER_EXIT = 0x0000000a
  627. };
  628. if (auto* topHandler = component.getAccessibilityHandler())
  629. {
  630. if (auto* virtualHandler = topHandler->getChildAt ((sysPos / scale).roundToInt()))
  631. {
  632. switch (command)
  633. {
  634. case ACTION_HOVER_ENTER:
  635. case ACTION_HOVER_MOVE:
  636. sendAccessibilityEventImpl (*virtualHandler, TYPE_VIEW_HOVER_ENTER, 0);
  637. break;
  638. case ACTION_HOVER_EXIT:
  639. sendAccessibilityEventImpl (*virtualHandler, TYPE_VIEW_HOVER_EXIT, 0);
  640. break;
  641. }
  642. }
  643. }
  644. }
  645. void handleKeyDownCallback (int k, int kc, int kbFlags)
  646. {
  647. ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withOnlyMouseButtons()
  648. .withFlags (translateAndroidKeyboardFlags (kbFlags));
  649. handleKeyPress (translateAndroidKeyCode (k), static_cast<juce_wchar> (kc));
  650. }
  651. void handleKeyUpCallback (int /*k*/, int /*kc*/)
  652. {
  653. }
  654. void handleBackButtonCallback()
  655. {
  656. bool handled = false;
  657. if (auto* app = JUCEApplicationBase::getInstance())
  658. handled = app->backButtonPressed();
  659. if (isKioskModeComponent())
  660. setNavBarsHidden (navBarsHidden);
  661. if (! handled)
  662. {
  663. auto* env = getEnv();
  664. LocalRef<jobject> activity (getCurrentActivity());
  665. if (activity != nullptr)
  666. {
  667. jmethodID finishMethod = env->GetMethodID (AndroidActivity, "finish", "()V");
  668. if (finishMethod != nullptr)
  669. env->CallVoidMethod (activity.get(), finishMethod);
  670. }
  671. }
  672. }
  673. void handleKeyboardHiddenCallback()
  674. {
  675. Component::unfocusAllComponents();
  676. }
  677. void handleAppPausedCallback() {}
  678. void handleAppResumedCallback()
  679. {
  680. if (isKioskModeComponent())
  681. setNavBarsHidden (navBarsHidden);
  682. }
  683. //==============================================================================
  684. AccessibilityNativeHandle* getNativeHandleForViewId (jint virtualViewId) const
  685. {
  686. if (auto* handler = (virtualViewId == HOST_VIEW_ID
  687. ? component.getAccessibilityHandler()
  688. : AccessibilityNativeHandle::getAccessibilityHandlerForVirtualViewId (virtualViewId)))
  689. {
  690. return handler->getNativeImplementation();
  691. }
  692. return nullptr;
  693. }
  694. jboolean populateAccessibilityNodeInfoCallback (jint virtualViewId, jobject info) const
  695. {
  696. if (auto* handle = getNativeHandleForViewId (virtualViewId))
  697. {
  698. handle->populateNodeInfo (info);
  699. return true;
  700. }
  701. return false;
  702. }
  703. jboolean handlePerformActionCallback (jint virtualViewId, jint action, jobject arguments) const
  704. {
  705. if (auto* handle = getNativeHandleForViewId (virtualViewId))
  706. return handle->performAction (action, arguments);
  707. return false;
  708. }
  709. static jobject getFocusViewIdForHandler (const AccessibilityHandler* handler)
  710. {
  711. if (handler != nullptr)
  712. return getEnv()->NewObject (JavaInteger,
  713. JavaInteger.constructor,
  714. handler->getNativeImplementation()->getVirtualViewId());
  715. return nullptr;
  716. }
  717. jobject getInputFocusViewIdCallback()
  718. {
  719. if (auto* comp = dynamic_cast<Component*> (findCurrentTextInputTarget()))
  720. return getFocusViewIdForHandler (comp->getAccessibilityHandler());
  721. return nullptr;
  722. }
  723. jobject getAccessibilityFocusViewIdCallback() const
  724. {
  725. if (auto* handler = component.getAccessibilityHandler())
  726. {
  727. if (auto* modal = Component::getCurrentlyModalComponent())
  728. {
  729. if (! component.isParentOf (modal)
  730. && component.isCurrentlyBlockedByAnotherModalComponent())
  731. {
  732. if (auto* modalHandler = modal->getAccessibilityHandler())
  733. {
  734. if (auto* focusChild = modalHandler->getChildFocus())
  735. return getFocusViewIdForHandler (focusChild);
  736. return getFocusViewIdForHandler (modalHandler);
  737. }
  738. }
  739. }
  740. if (auto* focusChild = handler->getChildFocus())
  741. return getFocusViewIdForHandler (focusChild);
  742. }
  743. return nullptr;
  744. }
  745. //==============================================================================
  746. bool isFocused() const override
  747. {
  748. if (view != nullptr)
  749. return view.callBooleanMethod (AndroidView.hasFocus);
  750. return false;
  751. }
  752. void grabFocus() override
  753. {
  754. if (view != nullptr)
  755. view.callBooleanMethod (AndroidView.requestFocus);
  756. }
  757. void handleFocusChangeCallback (bool hasFocus)
  758. {
  759. if (isFullScreen())
  760. setFullScreen (true);
  761. if (hasFocus)
  762. handleFocusGain();
  763. else
  764. handleFocusLoss();
  765. }
  766. static const char* getVirtualKeyboardType (TextInputTarget::VirtualKeyboardType type) noexcept
  767. {
  768. switch (type)
  769. {
  770. case TextInputTarget::textKeyboard: return "text";
  771. case TextInputTarget::numericKeyboard: return "number";
  772. case TextInputTarget::decimalKeyboard: return "numberDecimal";
  773. case TextInputTarget::urlKeyboard: return "textUri";
  774. case TextInputTarget::emailAddressKeyboard: return "textEmailAddress";
  775. case TextInputTarget::phoneNumberKeyboard: return "phone";
  776. default: jassertfalse; break;
  777. }
  778. return "text";
  779. }
  780. void textInputRequired (Point<int>, TextInputTarget& target) override
  781. {
  782. view.callVoidMethod (ComponentPeerView.showKeyboard,
  783. javaString (getVirtualKeyboardType (target.getKeyboardType())).get());
  784. }
  785. void dismissPendingTextInput() override
  786. {
  787. view.callVoidMethod (ComponentPeerView.showKeyboard, javaString ("").get());
  788. if (! isTimerRunning())
  789. startTimer (500);
  790. }
  791. //==============================================================================
  792. void handlePaintCallback (jobject canvas, jobject paint)
  793. {
  794. auto* env = getEnv();
  795. jobject rect = env->CallObjectMethod (canvas, AndroidCanvas.getClipBounds);
  796. auto left = env->GetIntField (rect, AndroidRect.left);
  797. auto top = env->GetIntField (rect, AndroidRect.top);
  798. auto right = env->GetIntField (rect, AndroidRect.right);
  799. auto bottom = env->GetIntField (rect, AndroidRect.bottom);
  800. env->DeleteLocalRef (rect);
  801. auto clip = Rectangle<int>::leftTopRightBottom (left, top, right, bottom);
  802. if (clip.isEmpty())
  803. return;
  804. auto sizeNeeded = clip.getWidth() * clip.getHeight();
  805. if (sizeAllocated < sizeNeeded)
  806. {
  807. buffer.clear();
  808. sizeAllocated = sizeNeeded;
  809. buffer = GlobalRef (LocalRef<jobject> ((jobject) env->NewIntArray (sizeNeeded)));
  810. }
  811. if (jint* dest = env->GetIntArrayElements ((jintArray) buffer.get(), nullptr))
  812. {
  813. {
  814. Image temp (new PreallocatedImage (clip.getWidth(), clip.getHeight(),
  815. dest, ! component.isOpaque()));
  816. {
  817. LowLevelGraphicsSoftwareRenderer g (temp);
  818. g.setOrigin (-clip.getPosition());
  819. g.addTransform (AffineTransform::scale (scale));
  820. handlePaint (g);
  821. }
  822. }
  823. env->ReleaseIntArrayElements ((jintArray) buffer.get(), dest, 0);
  824. env->CallVoidMethod (canvas, AndroidCanvas.drawBitmap, (jintArray) buffer.get(), 0, clip.getWidth(),
  825. (jfloat) clip.getX(), (jfloat) clip.getY(),
  826. clip.getWidth(), clip.getHeight(), true, paint);
  827. }
  828. }
  829. void repaint (const Rectangle<int>& userArea) override
  830. {
  831. auto area = (userArea.toFloat() * scale).toNearestInt();
  832. GlobalRef localView (view);
  833. callOnMessageThread ([area, localView]
  834. {
  835. localView.callVoidMethod (AndroidView.invalidate,
  836. area.getX(), area.getY(), area.getRight(), area.getBottom());
  837. });
  838. }
  839. void performAnyPendingRepaintsNow() override
  840. {
  841. // TODO
  842. }
  843. void setAlpha (float /*newAlpha*/) override
  844. {
  845. // TODO
  846. }
  847. StringArray getAvailableRenderingEngines() override
  848. {
  849. return StringArray ("Software Renderer");
  850. }
  851. //==============================================================================
  852. static Point<float> lastMousePos;
  853. static int64 touchesDown;
  854. //==============================================================================
  855. struct StartupActivityCallbackListener : public ActivityLifecycleCallbacks
  856. {
  857. void onActivityStarted (jobject /*activity*/) override
  858. {
  859. auto* env = getEnv();
  860. LocalRef<jobject> appContext (getAppContext());
  861. if (appContext.get() != nullptr)
  862. {
  863. env->CallVoidMethod (appContext.get(),
  864. AndroidApplication.unregisterActivityLifecycleCallbacks,
  865. activityCallbackListener.get());
  866. clear();
  867. activityCallbackListener.clear();
  868. forceDisplayUpdate();
  869. }
  870. }
  871. };
  872. private:
  873. //==============================================================================
  874. #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
  875. METHOD (create, "<init>", "(Landroid/content/Context;ZJ)V") \
  876. METHOD (clear, "clear", "()V") \
  877. METHOD (setViewName, "setViewName", "(Ljava/lang/String;)V") \
  878. METHOD (setVisible, "setVisible", "(Z)V") \
  879. METHOD (isVisible, "isVisible", "()Z") \
  880. METHOD (containsPoint, "containsPoint", "(II)Z") \
  881. METHOD (showKeyboard, "showKeyboard", "(Ljava/lang/String;)V") \
  882. METHOD (setSystemUiVisibilityCompat, "setSystemUiVisibilityCompat", "(I)V") \
  883. CALLBACK (handlePaintJni, "handlePaint", "(JLandroid/graphics/Canvas;Landroid/graphics/Paint;)V") \
  884. CALLBACK (handleMouseDownJni, "handleMouseDown", "(JIFFJ)V") \
  885. CALLBACK (handleMouseDragJni, "handleMouseDrag", "(JIFFJ)V") \
  886. CALLBACK (handleMouseUpJni, "handleMouseUp", "(JIFFJ)V") \
  887. CALLBACK (handleAccessibleHoverJni, "handleAccessibilityHover", "(JIFFJ)V") \
  888. CALLBACK (handleKeyDownJni, "handleKeyDown", "(JIII)V") \
  889. CALLBACK (handleKeyUpJni, "handleKeyUp", "(JII)V") \
  890. CALLBACK (handleBackButtonJni, "handleBackButton", "(J)V") \
  891. CALLBACK (handleKeyboardHiddenJni, "handleKeyboardHidden", "(J)V") \
  892. CALLBACK (viewSizeChangedJni, "viewSizeChanged", "(J)V") \
  893. CALLBACK (focusChangedJni, "focusChanged", "(JZ)V") \
  894. CALLBACK (handleAppPausedJni, "handleAppPaused", "(J)V") \
  895. CALLBACK (handleAppResumedJni, "handleAppResumed", "(J)V") \
  896. CALLBACK (populateAccessibilityNodeInfoJni, "populateAccessibilityNodeInfo", "(JILandroid/view/accessibility/AccessibilityNodeInfo;)Z") \
  897. CALLBACK (handlePerformActionJni, "handlePerformAction", "(JIILandroid/os/Bundle;)Z") \
  898. CALLBACK (getInputFocusViewIdJni, "getInputFocusViewId", "(J)Ljava/lang/Integer;") \
  899. CALLBACK (getAccessibilityFocusViewIdJni, "getAccessibilityFocusViewId", "(J)Ljava/lang/Integer;") \
  900. DECLARE_JNI_CLASS_WITH_BYTECODE (ComponentPeerView, "com/rmsl/juce/ComponentPeerView", 16, javaComponentPeerView, sizeof (javaComponentPeerView))
  901. #undef JNI_CLASS_MEMBERS
  902. static void JNICALL handlePaintJni (JNIEnv*, jobject /*view*/, jlong host, jobject canvas, jobject paint) { if (auto* myself = reinterpret_cast<AndroidComponentPeer*> (host)) myself->handlePaintCallback (canvas, paint); }
  903. static void JNICALL handleMouseDownJni (JNIEnv*, jobject /*view*/, jlong host, jint i, jfloat x, jfloat y, jlong time) { if (auto* myself = reinterpret_cast<AndroidComponentPeer*> (host)) myself->handleMouseDownCallback (i, Point<float> ((float) x, (float) y), (int64) time); }
  904. static void JNICALL handleMouseDragJni (JNIEnv*, jobject /*view*/, jlong host, jint i, jfloat x, jfloat y, jlong time) { if (auto* myself = reinterpret_cast<AndroidComponentPeer*> (host)) myself->handleMouseDragCallback (i, Point<float> ((float) x, (float) y), (int64) time); }
  905. static void JNICALL handleMouseUpJni (JNIEnv*, jobject /*view*/, jlong host, jint i, jfloat x, jfloat y, jlong time) { if (auto* myself = reinterpret_cast<AndroidComponentPeer*> (host)) myself->handleMouseUpCallback (i, Point<float> ((float) x, (float) y), (int64) time); }
  906. static void JNICALL handleAccessibleHoverJni(JNIEnv*, jobject /*view*/, jlong host, jint c, jfloat x, jfloat y, jlong time) { if (auto* myself = reinterpret_cast<AndroidComponentPeer*> (host)) myself->handleAccessibilityHoverCallback ((int) c, Point<float> ((float) x, (float) y), (int64) time); }
  907. static void JNICALL viewSizeChangedJni (JNIEnv*, jobject /*view*/, jlong host) { if (auto* myself = reinterpret_cast<AndroidComponentPeer*> (host)) myself->handleMovedOrResized(); }
  908. static void JNICALL focusChangedJni (JNIEnv*, jobject /*view*/, jlong host, jboolean hasFocus) { if (auto* myself = reinterpret_cast<AndroidComponentPeer*> (host)) myself->handleFocusChangeCallback (hasFocus); }
  909. static void JNICALL handleKeyDownJni (JNIEnv*, jobject /*view*/, jlong host, jint k, jint kc, jint kbFlags) { if (auto* myself = reinterpret_cast<AndroidComponentPeer*> (host)) myself->handleKeyDownCallback ((int) k, (int) kc, (int) kbFlags); }
  910. static void JNICALL handleKeyUpJni (JNIEnv*, jobject /*view*/, jlong host, jint k, jint kc) { if (auto* myself = reinterpret_cast<AndroidComponentPeer*> (host)) myself->handleKeyUpCallback ((int) k, (int) kc); }
  911. static void JNICALL handleBackButtonJni (JNIEnv*, jobject /*view*/, jlong host) { if (auto* myself = reinterpret_cast<AndroidComponentPeer*> (host)) myself->handleBackButtonCallback(); }
  912. static void JNICALL handleKeyboardHiddenJni (JNIEnv*, jobject /*view*/, jlong host) { if (auto* myself = reinterpret_cast<AndroidComponentPeer*> (host)) myself->handleKeyboardHiddenCallback(); }
  913. static void JNICALL handleAppPausedJni (JNIEnv*, jobject /*view*/, jlong host) { if (auto* myself = reinterpret_cast<AndroidComponentPeer*> (host)) myself->handleAppPausedCallback(); }
  914. static void JNICALL handleAppResumedJni (JNIEnv*, jobject /*view*/, jlong host) { if (auto* myself = reinterpret_cast<AndroidComponentPeer*> (host)) myself->handleAppResumedCallback(); }
  915. static jboolean JNICALL populateAccessibilityNodeInfoJni (JNIEnv*, jobject /*view*/, jlong host, jint virtualViewId, jobject info)
  916. {
  917. if (auto* myself = reinterpret_cast<AndroidComponentPeer*> (host))
  918. return myself->populateAccessibilityNodeInfoCallback (virtualViewId, info);
  919. return false;
  920. }
  921. static jboolean JNICALL handlePerformActionJni (JNIEnv*, jobject /*view*/, jlong host, jint virtualViewId, jint action, jobject arguments)
  922. {
  923. if (auto* myself = reinterpret_cast<AndroidComponentPeer*> (host))
  924. return myself->handlePerformActionCallback (virtualViewId, action, arguments);
  925. return false;
  926. }
  927. static jobject JNICALL getInputFocusViewIdJni (JNIEnv*, jobject /*view*/, jlong host)
  928. {
  929. if (auto* myself = reinterpret_cast<AndroidComponentPeer*> (host))
  930. return myself->getInputFocusViewIdCallback();
  931. return nullptr;
  932. }
  933. static jobject JNICALL getAccessibilityFocusViewIdJni (JNIEnv*, jobject /*view*/, jlong host)
  934. {
  935. if (auto* myself = reinterpret_cast<AndroidComponentPeer*> (host))
  936. return myself->getAccessibilityFocusViewIdCallback();
  937. return nullptr;
  938. }
  939. //==============================================================================
  940. struct ViewWindowInsetsListener : public juce::AndroidInterfaceImplementer
  941. {
  942. jobject onApplyWindowInsets (LocalRef<jobject> v, LocalRef<jobject> insets)
  943. {
  944. auto* env = getEnv();
  945. LocalRef<jobject> displayCutout (env->CallObjectMethod (insets.get(), AndroidWindowInsets.getDisplayCutout));
  946. if (displayCutout != nullptr)
  947. {
  948. const auto& mainDisplay = *Desktop::getInstance().getDisplays().getPrimaryDisplay();
  949. auto newSafeAreaInsets = androidDisplayCutoutToBorderSize (displayCutout, mainDisplay.scale);
  950. if (newSafeAreaInsets != mainDisplay.safeAreaInsets)
  951. forceDisplayUpdate();
  952. auto* fieldId = env->GetStaticFieldID (AndroidWindowInsets, "CONSUMED", "Landroid/view/WindowInsets");
  953. jassert (fieldId != nullptr);
  954. return env->GetStaticObjectField (AndroidWindowInsets, fieldId);
  955. }
  956. jmethodID onApplyWindowInsetsMethodId = env->GetMethodID (AndroidView,
  957. "onApplyWindowInsets",
  958. "(Landroid/view/WindowInsets;)Landroid/view/WindowInsets;");
  959. jassert (onApplyWindowInsetsMethodId != nullptr);
  960. return env->CallObjectMethod (v.get(), onApplyWindowInsetsMethodId, insets.get());
  961. }
  962. private:
  963. jobject invoke (jobject proxy, jobject method, jobjectArray args) override
  964. {
  965. auto* env = getEnv();
  966. auto methodName = juce::juceString ((jstring) env->CallObjectMethod (method, JavaMethod.getName));
  967. if (methodName == "onApplyWindowInsets")
  968. {
  969. jassert (env->GetArrayLength (args) == 2);
  970. LocalRef<jobject> windowView (env->GetObjectArrayElement (args, 0));
  971. LocalRef<jobject> insets (env->GetObjectArrayElement (args, 1));
  972. return onApplyWindowInsets (std::move (windowView), std::move (insets));
  973. }
  974. // invoke base class
  975. return AndroidInterfaceImplementer::invoke (proxy, method, args);
  976. }
  977. };
  978. //==============================================================================
  979. struct PreallocatedImage : public ImagePixelData
  980. {
  981. PreallocatedImage (int width_, int height_, jint* data_, bool hasAlpha_)
  982. : ImagePixelData (Image::ARGB, width_, height_), data (data_), hasAlpha (hasAlpha_)
  983. {
  984. if (hasAlpha_)
  985. zeromem (data_, static_cast<size_t> (width * height) * sizeof (jint));
  986. }
  987. ~PreallocatedImage() override
  988. {
  989. if (hasAlpha)
  990. {
  991. auto pix = (PixelARGB*) data;
  992. for (int i = width * height; --i >= 0;)
  993. {
  994. pix->unpremultiply();
  995. ++pix;
  996. }
  997. }
  998. }
  999. std::unique_ptr<ImageType> createType() const override
  1000. {
  1001. return std::make_unique<SoftwareImageType>();
  1002. }
  1003. std::unique_ptr<LowLevelGraphicsContext> createLowLevelContext() override
  1004. {
  1005. return std::make_unique<LowLevelGraphicsSoftwareRenderer> (Image (this));
  1006. }
  1007. void initialiseBitmapData (Image::BitmapData& bm, int x, int y, Image::BitmapData::ReadWriteMode /*mode*/) override
  1008. {
  1009. bm.lineStride = width * static_cast<int> (sizeof (jint));
  1010. bm.pixelStride = static_cast<int> (sizeof (jint));
  1011. bm.pixelFormat = Image::ARGB;
  1012. const auto offset = (size_t) x + (size_t) y * (size_t) width;
  1013. bm.data = (uint8*) (data + offset);
  1014. bm.size = sizeof (jint) * (((size_t) height * (size_t) width) - offset);
  1015. }
  1016. ImagePixelData::Ptr clone() override
  1017. {
  1018. auto s = new PreallocatedImage (width, height, nullptr, hasAlpha);
  1019. s->allocatedData.malloc (sizeof (jint) * static_cast<size_t> (width * height));
  1020. s->data = s->allocatedData;
  1021. memcpy (s->data, data, sizeof (jint) * static_cast<size_t> (width * height));
  1022. return s;
  1023. }
  1024. private:
  1025. jint* data;
  1026. HeapBlock<jint> allocatedData;
  1027. bool hasAlpha;
  1028. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PreallocatedImage)
  1029. };
  1030. //==============================================================================
  1031. void timerCallback() override
  1032. {
  1033. setNavBarsHidden (shouldNavBarsBeHidden (fullScreen));
  1034. setFullScreen (fullScreen);
  1035. stopTimer();
  1036. }
  1037. bool isKioskModeComponent() const
  1038. {
  1039. if (auto* kiosk = Desktop::getInstance().getKioskModeComponent())
  1040. return kiosk->getPeer() == this;
  1041. return false;
  1042. }
  1043. bool shouldNavBarsBeHidden (bool shouldBeFullScreen) const
  1044. {
  1045. return (shouldBeFullScreen && isKioskModeComponent());
  1046. }
  1047. void setNavBarsHidden (bool hidden)
  1048. {
  1049. if (navBarsHidden != hidden)
  1050. {
  1051. navBarsHidden = hidden;
  1052. view.callVoidMethod (ComponentPeerView.setSystemUiVisibilityCompat,
  1053. (navBarsHidden ? (jint) (fullScreenFlags) : (jint) (SYSTEM_UI_FLAG_VISIBLE)));
  1054. }
  1055. }
  1056. template <typename Callback>
  1057. static void callOnMessageThread (Callback&& callback)
  1058. {
  1059. if (MessageManager::getInstance()->isThisTheMessageThread())
  1060. callback();
  1061. else
  1062. MessageManager::callAsync (std::forward<Callback> (callback));
  1063. }
  1064. //==============================================================================
  1065. friend class Displays;
  1066. static AndroidComponentPeer* frontWindow;
  1067. static GlobalRef activityCallbackListener;
  1068. static constexpr int GRAVITY_LEFT = 0x3, GRAVITY_TOP = 0x30;
  1069. static constexpr int TYPE_APPLICATION = 0x2;
  1070. static constexpr int FLAG_NOT_TOUCH_MODAL = 0x20, FLAG_LAYOUT_IN_SCREEN = 0x100, FLAG_LAYOUT_NO_LIMITS = 0x200;
  1071. static constexpr int PIXEL_FORMAT_OPAQUE = -1, PIXEL_FORMAT_TRANSPARENT = -2;
  1072. static constexpr int LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS = 0x3;
  1073. GlobalRef view, viewGroup, buffer;
  1074. bool viewGroupIsWindow = false, fullScreen = false, navBarsHidden = false;
  1075. int sizeAllocated = 0;
  1076. float scale = (float) Desktop::getInstance().getDisplays().getPrimaryDisplay()->scale;
  1077. //==============================================================================
  1078. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AndroidComponentPeer)
  1079. };
  1080. Point<float> AndroidComponentPeer::lastMousePos;
  1081. int64 AndroidComponentPeer::touchesDown = 0;
  1082. AndroidComponentPeer* AndroidComponentPeer::frontWindow = nullptr;
  1083. GlobalRef AndroidComponentPeer::activityCallbackListener;
  1084. AndroidComponentPeer::ComponentPeerView_Class AndroidComponentPeer::ComponentPeerView;
  1085. //==============================================================================
  1086. ComponentPeer* Component::createNewPeer (int styleFlags, void* nativeWindow)
  1087. {
  1088. return new AndroidComponentPeer (*this, styleFlags, nativeWindow);
  1089. }
  1090. //==============================================================================
  1091. bool Desktop::canUseSemiTransparentWindows() noexcept
  1092. {
  1093. return true;
  1094. }
  1095. class Desktop::NativeDarkModeChangeDetectorImpl : public ActivityLifecycleCallbacks
  1096. {
  1097. public:
  1098. NativeDarkModeChangeDetectorImpl()
  1099. {
  1100. LocalRef<jobject> appContext (getAppContext());
  1101. if (appContext != nullptr)
  1102. {
  1103. auto* env = getEnv();
  1104. myself = GlobalRef (CreateJavaInterface (this, "android/app/Application$ActivityLifecycleCallbacks"));
  1105. env->CallVoidMethod (appContext.get(), AndroidApplication.registerActivityLifecycleCallbacks, myself.get());
  1106. }
  1107. }
  1108. ~NativeDarkModeChangeDetectorImpl() override
  1109. {
  1110. LocalRef<jobject> appContext (getAppContext());
  1111. if (appContext != nullptr && myself != nullptr)
  1112. {
  1113. auto* env = getEnv();
  1114. env->CallVoidMethod (appContext.get(),
  1115. AndroidApplication.unregisterActivityLifecycleCallbacks,
  1116. myself.get());
  1117. clear();
  1118. myself.clear();
  1119. }
  1120. }
  1121. bool isDarkModeEnabled() const noexcept { return darkModeEnabled; }
  1122. void onActivityStarted (jobject /*activity*/) override
  1123. {
  1124. const auto isEnabled = getDarkModeSetting();
  1125. if (darkModeEnabled != isEnabled)
  1126. {
  1127. darkModeEnabled = isEnabled;
  1128. Desktop::getInstance().darkModeChanged();
  1129. }
  1130. }
  1131. private:
  1132. static bool getDarkModeSetting()
  1133. {
  1134. auto* env = getEnv();
  1135. const LocalRef<jobject> resources (env->CallObjectMethod (getAppContext().get(), AndroidContext.getResources));
  1136. const LocalRef<jobject> configuration (env->CallObjectMethod (resources, AndroidResources.getConfiguration));
  1137. const auto uiMode = env->GetIntField (configuration, AndroidConfiguration.uiMode);
  1138. return ((uiMode & UI_MODE_NIGHT_MASK) == UI_MODE_NIGHT_YES);
  1139. }
  1140. static constexpr int UI_MODE_NIGHT_MASK = 0x00000030,
  1141. UI_MODE_NIGHT_NO = 0x00000010,
  1142. UI_MODE_NIGHT_UNDEFINED = 0x00000000,
  1143. UI_MODE_NIGHT_YES = 0x00000020;
  1144. GlobalRef myself;
  1145. bool darkModeEnabled = getDarkModeSetting();
  1146. //==============================================================================
  1147. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NativeDarkModeChangeDetectorImpl)
  1148. };
  1149. std::unique_ptr<Desktop::NativeDarkModeChangeDetectorImpl> Desktop::createNativeDarkModeChangeDetectorImpl()
  1150. {
  1151. return std::make_unique<NativeDarkModeChangeDetectorImpl>();
  1152. }
  1153. bool Desktop::isDarkModeActive() const
  1154. {
  1155. return nativeDarkModeChangeDetectorImpl->isDarkModeEnabled();
  1156. }
  1157. double Desktop::getDefaultMasterScale()
  1158. {
  1159. return 1.0;
  1160. }
  1161. Desktop::DisplayOrientation Desktop::getCurrentOrientation() const
  1162. {
  1163. enum
  1164. {
  1165. ROTATION_0 = 0,
  1166. ROTATION_90 = 1,
  1167. ROTATION_180 = 2,
  1168. ROTATION_270 = 3
  1169. };
  1170. JNIEnv* env = getEnv();
  1171. LocalRef<jstring> windowServiceString (javaString ("window"));
  1172. LocalRef<jobject> windowManager = LocalRef<jobject> (env->CallObjectMethod (getAppContext().get(), AndroidContext.getSystemService, windowServiceString.get()));
  1173. if (windowManager.get() != nullptr)
  1174. {
  1175. LocalRef<jobject> display = LocalRef<jobject> (env->CallObjectMethod (windowManager, AndroidWindowManager.getDefaultDisplay));
  1176. if (display.get() != nullptr)
  1177. {
  1178. int rotation = env->CallIntMethod (display, AndroidDisplay.getRotation);
  1179. switch (rotation)
  1180. {
  1181. case ROTATION_0: return upright;
  1182. case ROTATION_90: return rotatedAntiClockwise;
  1183. case ROTATION_180: return upsideDown;
  1184. case ROTATION_270: return rotatedClockwise;
  1185. }
  1186. }
  1187. }
  1188. jassertfalse;
  1189. return upright;
  1190. }
  1191. bool MouseInputSource::SourceList::addSource()
  1192. {
  1193. addSource (sources.size(), MouseInputSource::InputSourceType::touch);
  1194. return true;
  1195. }
  1196. bool MouseInputSource::SourceList::canUseTouch()
  1197. {
  1198. return true;
  1199. }
  1200. Point<float> MouseInputSource::getCurrentRawMousePosition()
  1201. {
  1202. return AndroidComponentPeer::lastMousePos;
  1203. }
  1204. void MouseInputSource::setRawMousePosition (Point<float>)
  1205. {
  1206. // not needed
  1207. }
  1208. //==============================================================================
  1209. bool KeyPress::isKeyCurrentlyDown (int /*keyCode*/)
  1210. {
  1211. // TODO
  1212. return false;
  1213. }
  1214. JUCE_API void JUCE_CALLTYPE Process::hide()
  1215. {
  1216. auto* env = getEnv();
  1217. LocalRef<jobject> currentActivity (getCurrentActivity().get());
  1218. if (env->CallBooleanMethod (currentActivity.get(), AndroidActivity.moveTaskToBack, true) == 0)
  1219. {
  1220. GlobalRef intent (LocalRef<jobject> (env->NewObject (AndroidIntent, AndroidIntent.constructor)));
  1221. env->CallObjectMethod (intent, AndroidIntent.setAction, javaString ("android.intent.action.MAIN") .get());
  1222. env->CallObjectMethod (intent, AndroidIntent.addCategory, javaString ("android.intent.category.HOME").get());
  1223. env->CallVoidMethod (currentActivity.get(), AndroidContext.startActivity, intent.get());
  1224. }
  1225. }
  1226. //==============================================================================
  1227. // TODO
  1228. JUCE_API bool JUCE_CALLTYPE Process::isForegroundProcess() { return true; }
  1229. JUCE_API void JUCE_CALLTYPE Process::makeForegroundProcess() {}
  1230. //==============================================================================
  1231. #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
  1232. METHOD (show, "show", "()V") \
  1233. METHOD (getWindow, "getWindow", "()Landroid/view/Window;")
  1234. DECLARE_JNI_CLASS (AndroidDialog, "android/app/Dialog")
  1235. #undef JNI_CLASS_MEMBERS
  1236. #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
  1237. METHOD (construct, "<init>", "(Landroid/content/Context;)V") \
  1238. METHOD (create, "create", "()Landroid/app/AlertDialog;") \
  1239. METHOD (setTitle, "setTitle", "(Ljava/lang/CharSequence;)Landroid/app/AlertDialog$Builder;") \
  1240. METHOD (setMessage, "setMessage", "(Ljava/lang/CharSequence;)Landroid/app/AlertDialog$Builder;") \
  1241. METHOD (setCancelable, "setCancelable", "(Z)Landroid/app/AlertDialog$Builder;") \
  1242. METHOD (setOnCancelListener, "setOnCancelListener", "(Landroid/content/DialogInterface$OnCancelListener;)Landroid/app/AlertDialog$Builder;") \
  1243. METHOD (setPositiveButton, "setPositiveButton", "(Ljava/lang/CharSequence;Landroid/content/DialogInterface$OnClickListener;)Landroid/app/AlertDialog$Builder;") \
  1244. METHOD (setNegativeButton, "setNegativeButton", "(Ljava/lang/CharSequence;Landroid/content/DialogInterface$OnClickListener;)Landroid/app/AlertDialog$Builder;") \
  1245. METHOD (setNeutralButton, "setNeutralButton", "(Ljava/lang/CharSequence;Landroid/content/DialogInterface$OnClickListener;)Landroid/app/AlertDialog$Builder;")
  1246. DECLARE_JNI_CLASS (AndroidAlertDialogBuilder, "android/app/AlertDialog$Builder")
  1247. #undef JNI_CLASS_MEMBERS
  1248. #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
  1249. METHOD (dismiss, "dismiss", "()V")
  1250. DECLARE_JNI_CLASS (AndroidDialogInterface, "android/content/DialogInterface")
  1251. #undef JNI_CLASS_MEMBERS
  1252. #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
  1253. DECLARE_JNI_CLASS (AndroidDialogOnClickListener, "android/content/DialogInterface$OnClickListener")
  1254. #undef JNI_CLASS_MEMBERS
  1255. //==============================================================================
  1256. class DialogListener : public juce::AndroidInterfaceImplementer
  1257. {
  1258. public:
  1259. DialogListener (std::shared_ptr<ModalComponentManager::Callback> callbackToUse, int resultToUse)
  1260. : callback (std::move (callbackToUse)), result (resultToUse)
  1261. {}
  1262. void onResult (jobject dialog)
  1263. {
  1264. auto* env = getEnv();
  1265. env->CallVoidMethod (dialog, AndroidDialogInterface.dismiss);
  1266. if (callback != nullptr)
  1267. callback->modalStateFinished (result);
  1268. callback = nullptr;
  1269. }
  1270. private:
  1271. jobject invoke (jobject proxy, jobject method, jobjectArray args) override
  1272. {
  1273. auto* env = getEnv();
  1274. auto methodName = juce::juceString ((jstring) env->CallObjectMethod (method, JavaMethod.getName));
  1275. if (methodName == "onCancel" || methodName == "onClick")
  1276. {
  1277. onResult (env->GetObjectArrayElement (args, 0));
  1278. return nullptr;
  1279. }
  1280. // invoke base class
  1281. return AndroidInterfaceImplementer::invoke (proxy, method, args);
  1282. }
  1283. std::shared_ptr<ModalComponentManager::Callback> callback;
  1284. int result;
  1285. };
  1286. //==============================================================================
  1287. static void createAndroidDialog (const MessageBoxOptions& opts,
  1288. ModalComponentManager::Callback* callbackIn,
  1289. AlertWindowMappings::MapFn mapFn)
  1290. {
  1291. auto* env = getEnv();
  1292. LocalRef<jobject> builder (env->NewObject (AndroidAlertDialogBuilder, AndroidAlertDialogBuilder.construct, getMainActivity().get()));
  1293. builder = LocalRef<jobject> (env->CallObjectMethod (builder.get(), AndroidAlertDialogBuilder.setTitle, javaString (opts.getTitle()).get()));
  1294. builder = LocalRef<jobject> (env->CallObjectMethod (builder.get(), AndroidAlertDialogBuilder.setMessage, javaString (opts.getMessage()).get()));
  1295. builder = LocalRef<jobject> (env->CallObjectMethod (builder.get(), AndroidAlertDialogBuilder.setCancelable, true));
  1296. std::shared_ptr<ModalComponentManager::Callback> sharedCallback (AlertWindowMappings::getWrappedCallback (callbackIn, mapFn));
  1297. builder = LocalRef<jobject> (env->CallObjectMethod (builder.get(), AndroidAlertDialogBuilder.setOnCancelListener,
  1298. CreateJavaInterface (new DialogListener (sharedCallback, 0),
  1299. "android/content/DialogInterface$OnCancelListener").get()));
  1300. builder = LocalRef<jobject> (env->CallObjectMethod (builder.get(), AndroidAlertDialogBuilder.setPositiveButton,
  1301. javaString (opts.getButtonText (0)).get(),
  1302. CreateJavaInterface (new DialogListener (sharedCallback, 0),
  1303. "android/content/DialogInterface$OnClickListener").get()));
  1304. if (opts.getButtonText (1).isNotEmpty())
  1305. builder = LocalRef<jobject> (env->CallObjectMethod (builder.get(), AndroidAlertDialogBuilder.setNegativeButton,
  1306. javaString (opts.getButtonText (1)).get(),
  1307. CreateJavaInterface (new DialogListener (sharedCallback, 1),
  1308. "android/content/DialogInterface$OnClickListener").get()));
  1309. if (opts.getButtonText (2).isNotEmpty())
  1310. builder = LocalRef<jobject> (env->CallObjectMethod (builder.get(), AndroidAlertDialogBuilder.setNeutralButton,
  1311. javaString (opts.getButtonText (2)).get(),
  1312. CreateJavaInterface (new DialogListener (sharedCallback, 2),
  1313. "android/content/DialogInterface$OnClickListener").get()));
  1314. LocalRef<jobject> dialog (env->CallObjectMethod (builder.get(), AndroidAlertDialogBuilder.create));
  1315. LocalRef<jobject> window (env->CallObjectMethod (dialog.get(), AndroidDialog.getWindow));
  1316. if (Desktop::getInstance().getKioskModeComponent() != nullptr)
  1317. {
  1318. env->CallVoidMethod (window.get(), AndroidWindow.setFlags, FLAG_NOT_FOCUSABLE, FLAG_NOT_FOCUSABLE);
  1319. LocalRef<jobject> decorView (env->CallObjectMethod (window.get(), AndroidWindow.getDecorView));
  1320. env->CallVoidMethod (decorView.get(), AndroidView.setSystemUiVisibility, fullScreenFlags);
  1321. }
  1322. env->CallVoidMethod (dialog.get(), AndroidDialog.show);
  1323. if (Desktop::getInstance().getKioskModeComponent() != nullptr)
  1324. env->CallVoidMethod (window.get(), AndroidWindow.clearFlags, FLAG_NOT_FOCUSABLE);
  1325. }
  1326. void JUCE_CALLTYPE NativeMessageBox::showMessageBoxAsync (MessageBoxIconType /*iconType*/,
  1327. const String& title, const String& message,
  1328. Component* /*associatedComponent*/,
  1329. ModalComponentManager::Callback* callback)
  1330. {
  1331. createAndroidDialog (MessageBoxOptions()
  1332. .withTitle (title)
  1333. .withMessage (message)
  1334. .withButton (TRANS("OK")),
  1335. callback, AlertWindowMappings::messageBox);
  1336. }
  1337. bool JUCE_CALLTYPE NativeMessageBox::showOkCancelBox (MessageBoxIconType /*iconType*/,
  1338. const String& title, const String& message,
  1339. Component* /*associatedComponent*/,
  1340. ModalComponentManager::Callback* callback)
  1341. {
  1342. createAndroidDialog (MessageBoxOptions()
  1343. .withTitle (title)
  1344. .withMessage (message)
  1345. .withButton (TRANS("OK"))
  1346. .withButton (TRANS("Cancel")),
  1347. callback, AlertWindowMappings::okCancel);
  1348. return false;
  1349. }
  1350. int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (MessageBoxIconType /*iconType*/,
  1351. const String& title, const String& message,
  1352. Component* /*associatedComponent*/,
  1353. ModalComponentManager::Callback* callback)
  1354. {
  1355. createAndroidDialog (MessageBoxOptions()
  1356. .withTitle (title)
  1357. .withMessage (message)
  1358. .withButton (TRANS("Yes"))
  1359. .withButton (TRANS("No"))
  1360. .withButton (TRANS("Cancel")),
  1361. callback, AlertWindowMappings::yesNoCancel);
  1362. return 0;
  1363. }
  1364. int JUCE_CALLTYPE NativeMessageBox::showYesNoBox (MessageBoxIconType /*iconType*/,
  1365. const String& title, const String& message,
  1366. Component* /*associatedComponent*/,
  1367. ModalComponentManager::Callback* callback)
  1368. {
  1369. createAndroidDialog (MessageBoxOptions()
  1370. .withTitle (title)
  1371. .withMessage (message)
  1372. .withButton (TRANS("Yes"))
  1373. .withButton (TRANS("No")),
  1374. callback, AlertWindowMappings::okCancel);
  1375. return 0;
  1376. }
  1377. void JUCE_CALLTYPE NativeMessageBox::showAsync (const MessageBoxOptions& options,
  1378. ModalComponentManager::Callback* callback)
  1379. {
  1380. createAndroidDialog (options, callback, AlertWindowMappings::noMapping);
  1381. }
  1382. void JUCE_CALLTYPE NativeMessageBox::showAsync (const MessageBoxOptions& options,
  1383. std::function<void (int)> callback)
  1384. {
  1385. showAsync (options, ModalCallbackFunction::create (callback));
  1386. }
  1387. //==============================================================================
  1388. static bool androidScreenSaverEnabled = true;
  1389. void Desktop::setScreenSaverEnabled (bool shouldEnable)
  1390. {
  1391. constexpr auto FLAG_KEEP_SCREEN_ON = 0x80;
  1392. if (shouldEnable != androidScreenSaverEnabled)
  1393. {
  1394. LocalRef<jobject> activity (getMainActivity());
  1395. if (activity != nullptr)
  1396. {
  1397. auto* env = getEnv();
  1398. LocalRef<jobject> mainWindow (env->CallObjectMethod (activity.get(), AndroidActivity.getWindow));
  1399. env->CallVoidMethod (mainWindow.get(), AndroidWindow.setFlags, shouldEnable ? 0 : FLAG_KEEP_SCREEN_ON, FLAG_KEEP_SCREEN_ON);
  1400. }
  1401. androidScreenSaverEnabled = shouldEnable;
  1402. }
  1403. }
  1404. bool Desktop::isScreenSaverEnabled()
  1405. {
  1406. return androidScreenSaverEnabled;
  1407. }
  1408. //==============================================================================
  1409. void Desktop::setKioskComponent (Component* kioskComp, bool enableOrDisable, bool allowMenusAndBars)
  1410. {
  1411. ignoreUnused (allowMenusAndBars);
  1412. if (AndroidComponentPeer* peer = dynamic_cast<AndroidComponentPeer*> (kioskComp->getPeer()))
  1413. peer->setFullScreen (enableOrDisable);
  1414. else
  1415. jassertfalse; // (this should have been checked by the caller)
  1416. }
  1417. //==============================================================================
  1418. static jint getAndroidOrientationFlag (int orientations) noexcept
  1419. {
  1420. enum
  1421. {
  1422. SCREEN_ORIENTATION_LANDSCAPE = 0,
  1423. SCREEN_ORIENTATION_PORTRAIT = 1,
  1424. SCREEN_ORIENTATION_USER = 2,
  1425. SCREEN_ORIENTATION_REVERSE_LANDSCAPE = 8,
  1426. SCREEN_ORIENTATION_REVERSE_PORTRAIT = 9,
  1427. SCREEN_ORIENTATION_USER_LANDSCAPE = 11,
  1428. SCREEN_ORIENTATION_USER_PORTRAIT = 12,
  1429. };
  1430. switch (orientations)
  1431. {
  1432. case Desktop::upright: return (jint) SCREEN_ORIENTATION_PORTRAIT;
  1433. case Desktop::upsideDown: return (jint) SCREEN_ORIENTATION_REVERSE_PORTRAIT;
  1434. case Desktop::upright + Desktop::upsideDown: return (jint) SCREEN_ORIENTATION_USER_PORTRAIT;
  1435. case Desktop::rotatedAntiClockwise: return (jint) SCREEN_ORIENTATION_LANDSCAPE;
  1436. case Desktop::rotatedClockwise: return (jint) SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
  1437. case Desktop::rotatedClockwise + Desktop::rotatedAntiClockwise: return (jint) SCREEN_ORIENTATION_USER_LANDSCAPE;
  1438. default: return (jint) SCREEN_ORIENTATION_USER;
  1439. }
  1440. }
  1441. void Desktop::allowedOrientationsChanged()
  1442. {
  1443. LocalRef<jobject> activity (getMainActivity());
  1444. if (activity != nullptr)
  1445. getEnv()->CallVoidMethod (activity.get(), AndroidActivity.setRequestedOrientation, getAndroidOrientationFlag (allowedOrientations));
  1446. }
  1447. //==============================================================================
  1448. bool juce_areThereAnyAlwaysOnTopWindows()
  1449. {
  1450. return false;
  1451. }
  1452. //==============================================================================
  1453. #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
  1454. METHOD (create, "<init>", "()V") \
  1455. FIELD (density, "density", "F") \
  1456. FIELD (widthPixels, "widthPixels", "I") \
  1457. FIELD (heightPixels, "heightPixels", "I")
  1458. DECLARE_JNI_CLASS (AndroidDisplayMetrics, "android/util/DisplayMetrics")
  1459. #undef JNI_CLASS_MEMBERS
  1460. //==============================================================================
  1461. class LayoutChangeListener : public juce::AndroidInterfaceImplementer
  1462. {
  1463. public:
  1464. virtual void onLayoutChange (LocalRef<jobject> view, int left, int top, int right, int bottom,
  1465. int oldLeft, int oldTop, int oldRight, int oldBottom) = 0;
  1466. private:
  1467. jobject invoke (jobject proxy, jobject method, jobjectArray args) override
  1468. {
  1469. auto* env = getEnv();
  1470. auto methodName = juce::juceString ((jstring) env->CallObjectMethod (method, JavaMethod.getName));
  1471. if (methodName == "onLayoutChange")
  1472. {
  1473. jassert (env->GetArrayLength (args) == 9);
  1474. LocalRef<jobject> view (env->GetObjectArrayElement (args, 0));
  1475. int dims[8];
  1476. for (int i = 1; i < 9; ++i)
  1477. {
  1478. LocalRef<jobject> integer (env->GetObjectArrayElement (args, i));
  1479. dims[i - 1] = env->CallIntMethod (integer.get(), JavaInteger.intValue);
  1480. }
  1481. onLayoutChange (std::move (view), dims[0], dims[1], dims[2], dims[3],
  1482. dims[4], dims[5], dims[6], dims[7]);
  1483. return nullptr;
  1484. }
  1485. // invoke base class
  1486. return AndroidInterfaceImplementer::invoke (proxy, method, args);
  1487. }
  1488. std::unique_ptr<ModalComponentManager::Callback> callback;
  1489. };
  1490. //==============================================================================
  1491. struct MainActivityWindowLayoutListener : public LayoutChangeListener
  1492. {
  1493. MainActivityWindowLayoutListener (std::function<void()>&& updateDisplaysCb)
  1494. : forceDisplayUpdate (std::move (updateDisplaysCb))
  1495. {
  1496. }
  1497. void onLayoutChange (LocalRef<jobject> /*view*/, int left, int top, int right, int bottom,
  1498. int oldLeft, int oldTop, int oldRight, int oldBottom) override
  1499. {
  1500. auto newBounds = Rectangle<int>::leftTopRightBottom (left, top, right, bottom);
  1501. auto oldBounds = Rectangle<int>::leftTopRightBottom (oldLeft, oldTop, oldRight, oldBottom);
  1502. if (newBounds != oldBounds)
  1503. {
  1504. const auto& mainDisplay = *Desktop::getInstance().getDisplays().getPrimaryDisplay();
  1505. auto userArea = (newBounds.toFloat() / mainDisplay.scale).toNearestInt();
  1506. if (userArea != mainDisplay.userArea)
  1507. forceDisplayUpdate();
  1508. }
  1509. }
  1510. std::function<void()> forceDisplayUpdate;
  1511. };
  1512. //==============================================================================
  1513. void Displays::findDisplays (float masterScale)
  1514. {
  1515. auto* env = getEnv();
  1516. LocalRef<jobject> usableSize (env->NewObject (AndroidPoint, AndroidPoint.create, 0, 0));
  1517. LocalRef<jstring> windowServiceString (javaString ("window"));
  1518. LocalRef<jobject> displayMetrics (env->NewObject (AndroidDisplayMetrics, AndroidDisplayMetrics.create));
  1519. LocalRef<jobject> windowManager (env->CallObjectMethod (getAppContext().get(), AndroidContext.getSystemService, windowServiceString.get()));
  1520. LocalRef <jobject> display (env->CallObjectMethod (windowManager, AndroidWindowManager.getDefaultDisplay));
  1521. jmethodID getRealMetricsMethod = env->GetMethodID (AndroidDisplay, "getRealMetrics", "(Landroid/util/DisplayMetrics;)V");
  1522. if (getRealMetricsMethod != nullptr)
  1523. env->CallVoidMethod (display.get(), getRealMetricsMethod, displayMetrics.get());
  1524. else
  1525. env->CallVoidMethod (display.get(), AndroidDisplay.getMetrics, displayMetrics.get());
  1526. env->CallVoidMethod (display.get(), AndroidDisplay.getSize, usableSize.get());
  1527. Display d;
  1528. d.isMain = true;
  1529. d.scale = env->GetFloatField (displayMetrics.get(), AndroidDisplayMetrics.density);
  1530. d.dpi = (d.scale * 160.f);
  1531. d.scale *= masterScale;
  1532. d.totalArea = Rectangle<int> (env->GetIntField (displayMetrics.get(), AndroidDisplayMetrics.widthPixels),
  1533. env->GetIntField (displayMetrics.get(), AndroidDisplayMetrics.heightPixels)) / d.scale;
  1534. d.userArea = Rectangle<int> (env->GetIntField (usableSize.get(), AndroidPoint.x),
  1535. env->GetIntField (usableSize.get(), AndroidPoint.y)) / d.scale;
  1536. // unfortunately usableSize still contains the nav bar
  1537. // the best workaround is to try to get the size of the top-level view of
  1538. // the main activity
  1539. LocalRef<jobject> activity (getMainActivity());
  1540. if (activity != nullptr)
  1541. {
  1542. LocalRef<jobject> mainWindow (env->CallObjectMethod (activity.get(), AndroidActivity.getWindow));
  1543. LocalRef<jobject> decorView (env->CallObjectMethod (mainWindow.get(), AndroidWindow.getDecorView));
  1544. LocalRef<jobject> contentView (env->CallObjectMethod (decorView.get(), AndroidView.findViewById, 0x01020002 /* android.R.id.content */));
  1545. if (contentView != nullptr)
  1546. {
  1547. Rectangle<int> activityArea (env->CallIntMethod (contentView.get(), AndroidView.getLeft),
  1548. env->CallIntMethod (contentView.get(), AndroidView.getTop),
  1549. env->CallIntMethod (contentView.get(), AndroidView.getWidth),
  1550. env->CallIntMethod (contentView.get(), AndroidView.getHeight));
  1551. if (! activityArea.isEmpty())
  1552. d.userArea = activityArea / d.scale;
  1553. if (supportsDisplayCutout())
  1554. {
  1555. jmethodID getRootWindowInsetsMethodId = env->GetMethodID (AndroidView,
  1556. "getRootWindowInsets",
  1557. "()Landroid/view/WindowInsets;");
  1558. if (getRootWindowInsetsMethodId != nullptr)
  1559. {
  1560. LocalRef<jobject> insets (env->CallObjectMethod (contentView.get(), getRootWindowInsetsMethodId));
  1561. if (insets != nullptr)
  1562. {
  1563. LocalRef<jobject> displayCutout (env->CallObjectMethod (insets.get(), AndroidWindowInsets.getDisplayCutout));
  1564. if (displayCutout.get() != nullptr)
  1565. d.safeAreaInsets = androidDisplayCutoutToBorderSize (displayCutout, d.scale);
  1566. }
  1567. }
  1568. }
  1569. static bool hasAddedMainActivityListener = false;
  1570. if (! hasAddedMainActivityListener)
  1571. {
  1572. hasAddedMainActivityListener = true;
  1573. env->CallVoidMethod (contentView.get(), AndroidView.addOnLayoutChangeListener,
  1574. CreateJavaInterface (new MainActivityWindowLayoutListener ([this] { refresh(); }),
  1575. "android/view/View$OnLayoutChangeListener").get());
  1576. }
  1577. }
  1578. }
  1579. else
  1580. {
  1581. // the main activity may have not started yet so add an activity listener
  1582. if (AndroidComponentPeer::activityCallbackListener == nullptr)
  1583. {
  1584. LocalRef<jobject> appContext (getAppContext());
  1585. if (appContext.get() != nullptr)
  1586. {
  1587. AndroidComponentPeer::activityCallbackListener = GlobalRef (CreateJavaInterface (
  1588. new AndroidComponentPeer::StartupActivityCallbackListener,
  1589. "android/app/Application$ActivityLifecycleCallbacks"));
  1590. env->CallVoidMethod (appContext.get(),
  1591. AndroidApplication.registerActivityLifecycleCallbacks,
  1592. AndroidComponentPeer::activityCallbackListener.get());
  1593. }
  1594. }
  1595. }
  1596. displays.add (d);
  1597. }
  1598. //==============================================================================
  1599. Image juce_createIconForFile (const File& /*file*/)
  1600. {
  1601. return Image();
  1602. }
  1603. //==============================================================================
  1604. class MouseCursor::PlatformSpecificHandle
  1605. {
  1606. public:
  1607. PlatformSpecificHandle (const MouseCursor::StandardCursorType) {}
  1608. PlatformSpecificHandle (const CustomMouseCursorInfo&) {}
  1609. static void showInWindow (PlatformSpecificHandle*, ComponentPeer*) {}
  1610. };
  1611. //==============================================================================
  1612. bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& /*files*/, bool /*canMove*/,
  1613. Component* /*srcComp*/, std::function<void()> /*callback*/)
  1614. {
  1615. jassertfalse; // no such thing on Android!
  1616. return false;
  1617. }
  1618. bool DragAndDropContainer::performExternalDragDropOfText (const String& /*text*/, Component* /*srcComp*/,
  1619. std::function<void()> /*callback*/)
  1620. {
  1621. jassertfalse; // no such thing on Android!
  1622. return false;
  1623. }
  1624. //==============================================================================
  1625. void LookAndFeel::playAlertSound()
  1626. {
  1627. }
  1628. //==============================================================================
  1629. #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
  1630. METHOD (getText, "getText", "()Ljava/lang/CharSequence;") \
  1631. METHOD (setText, "setText", "(Ljava/lang/CharSequence;)V")
  1632. DECLARE_JNI_CLASS (AndroidClipboardManager, "android/content/ClipboardManager")
  1633. #undef JNI_CLASS_MEMBERS
  1634. //==============================================================================
  1635. void SystemClipboard::copyTextToClipboard (const String& text)
  1636. {
  1637. auto* env = getEnv();
  1638. LocalRef<jobject> clipboardManager (env->CallObjectMethod (getAppContext().get(), AndroidContext.getSystemService, javaString ("clipboard").get()));
  1639. env->CallVoidMethod (clipboardManager.get(), AndroidClipboardManager.setText, javaString(text).get());
  1640. }
  1641. String SystemClipboard::getTextFromClipboard()
  1642. {
  1643. auto* env = getEnv();
  1644. LocalRef<jobject> clipboardManager (env->CallObjectMethod (getAppContext().get(), AndroidContext.getSystemService, javaString ("clipboard").get()));
  1645. LocalRef<jobject> charSequence (env->CallObjectMethod (clipboardManager.get(), AndroidClipboardManager.getText));
  1646. if (charSequence == nullptr)
  1647. return {};
  1648. return juceString(LocalRef<jstring> ((jstring) env->CallObjectMethod(charSequence.get(), JavaCharSequence.toString)));
  1649. }
  1650. //==============================================================================
  1651. constexpr int extendedKeyModifier = 0x10000;
  1652. const int KeyPress::spaceKey = ' ';
  1653. const int KeyPress::returnKey = extendedKeyModifier + 2;
  1654. const int KeyPress::escapeKey = extendedKeyModifier + 3;
  1655. const int KeyPress::backspaceKey = extendedKeyModifier + 4;
  1656. const int KeyPress::leftKey = extendedKeyModifier + 5;
  1657. const int KeyPress::rightKey = extendedKeyModifier + 6;
  1658. const int KeyPress::upKey = extendedKeyModifier + 7;
  1659. const int KeyPress::downKey = extendedKeyModifier + 8;
  1660. const int KeyPress::pageUpKey = extendedKeyModifier + 9;
  1661. const int KeyPress::pageDownKey = extendedKeyModifier + 10;
  1662. const int KeyPress::endKey = extendedKeyModifier + 11;
  1663. const int KeyPress::homeKey = extendedKeyModifier + 12;
  1664. const int KeyPress::deleteKey = extendedKeyModifier + 13;
  1665. const int KeyPress::insertKey = extendedKeyModifier + 14;
  1666. const int KeyPress::tabKey = extendedKeyModifier + 15;
  1667. const int KeyPress::F1Key = extendedKeyModifier + 16;
  1668. const int KeyPress::F2Key = extendedKeyModifier + 17;
  1669. const int KeyPress::F3Key = extendedKeyModifier + 18;
  1670. const int KeyPress::F4Key = extendedKeyModifier + 19;
  1671. const int KeyPress::F5Key = extendedKeyModifier + 20;
  1672. const int KeyPress::F6Key = extendedKeyModifier + 21;
  1673. const int KeyPress::F7Key = extendedKeyModifier + 22;
  1674. const int KeyPress::F8Key = extendedKeyModifier + 23;
  1675. const int KeyPress::F9Key = extendedKeyModifier + 24;
  1676. const int KeyPress::F10Key = extendedKeyModifier + 25;
  1677. const int KeyPress::F11Key = extendedKeyModifier + 26;
  1678. const int KeyPress::F12Key = extendedKeyModifier + 27;
  1679. const int KeyPress::F13Key = extendedKeyModifier + 28;
  1680. const int KeyPress::F14Key = extendedKeyModifier + 29;
  1681. const int KeyPress::F15Key = extendedKeyModifier + 30;
  1682. const int KeyPress::F16Key = extendedKeyModifier + 31;
  1683. const int KeyPress::F17Key = extendedKeyModifier + 32;
  1684. const int KeyPress::F18Key = extendedKeyModifier + 33;
  1685. const int KeyPress::F19Key = extendedKeyModifier + 34;
  1686. const int KeyPress::F20Key = extendedKeyModifier + 35;
  1687. const int KeyPress::F21Key = extendedKeyModifier + 36;
  1688. const int KeyPress::F22Key = extendedKeyModifier + 37;
  1689. const int KeyPress::F23Key = extendedKeyModifier + 38;
  1690. const int KeyPress::F24Key = extendedKeyModifier + 39;
  1691. const int KeyPress::F25Key = extendedKeyModifier + 40;
  1692. const int KeyPress::F26Key = extendedKeyModifier + 41;
  1693. const int KeyPress::F27Key = extendedKeyModifier + 42;
  1694. const int KeyPress::F28Key = extendedKeyModifier + 43;
  1695. const int KeyPress::F29Key = extendedKeyModifier + 44;
  1696. const int KeyPress::F30Key = extendedKeyModifier + 45;
  1697. const int KeyPress::F31Key = extendedKeyModifier + 46;
  1698. const int KeyPress::F32Key = extendedKeyModifier + 47;
  1699. const int KeyPress::F33Key = extendedKeyModifier + 48;
  1700. const int KeyPress::F34Key = extendedKeyModifier + 49;
  1701. const int KeyPress::F35Key = extendedKeyModifier + 50;
  1702. const int KeyPress::numberPad0 = extendedKeyModifier + 51;
  1703. const int KeyPress::numberPad1 = extendedKeyModifier + 52;
  1704. const int KeyPress::numberPad2 = extendedKeyModifier + 53;
  1705. const int KeyPress::numberPad3 = extendedKeyModifier + 54;
  1706. const int KeyPress::numberPad4 = extendedKeyModifier + 55;
  1707. const int KeyPress::numberPad5 = extendedKeyModifier + 56;
  1708. const int KeyPress::numberPad6 = extendedKeyModifier + 57;
  1709. const int KeyPress::numberPad7 = extendedKeyModifier + 58;
  1710. const int KeyPress::numberPad8 = extendedKeyModifier + 59;
  1711. const int KeyPress::numberPad9 = extendedKeyModifier + 60;
  1712. const int KeyPress::numberPadAdd = extendedKeyModifier + 61;
  1713. const int KeyPress::numberPadSubtract = extendedKeyModifier + 62;
  1714. const int KeyPress::numberPadMultiply = extendedKeyModifier + 63;
  1715. const int KeyPress::numberPadDivide = extendedKeyModifier + 64;
  1716. const int KeyPress::numberPadSeparator = extendedKeyModifier + 65;
  1717. const int KeyPress::numberPadDecimalPoint = extendedKeyModifier + 66;
  1718. const int KeyPress::numberPadEquals = extendedKeyModifier + 67;
  1719. const int KeyPress::numberPadDelete = extendedKeyModifier + 68;
  1720. const int KeyPress::playKey = extendedKeyModifier + 69;
  1721. const int KeyPress::stopKey = extendedKeyModifier + 70;
  1722. const int KeyPress::fastForwardKey = extendedKeyModifier + 71;
  1723. const int KeyPress::rewindKey = extendedKeyModifier + 72;
  1724. //==============================================================================
  1725. #ifdef JUCE_PUSH_NOTIFICATIONS_ACTIVITY
  1726. struct JuceActivityNewIntentListener
  1727. {
  1728. #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
  1729. CALLBACK (appNewIntent, "appNewIntent", "(Landroid/content/Intent;)V")
  1730. DECLARE_JNI_CLASS (JavaActivity, JUCE_PUSH_NOTIFICATIONS_ACTIVITY)
  1731. #undef JNI_CLASS_MEMBERS
  1732. static void JNICALL appNewIntent (JNIEnv*, jobject /*activity*/, jobject intentData)
  1733. {
  1734. juce_handleNotificationIntent (static_cast<void*> (intentData));
  1735. }
  1736. };
  1737. JuceActivityNewIntentListener::JavaActivity_Class JuceActivityNewIntentListener::JavaActivity;
  1738. #endif
  1739. } // namespace juce