/* ============================================================================== This file is part of the JUCE 6 technical preview. Copyright (c) 2020 - Raw Material Software Limited You may use this code under the terms of the GPL v3 (see www.gnu.org/licenses). For this technical preview, this file is not subject to commercial licensing. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE DISCLAIMED. ============================================================================== */ namespace juce { // This byte-code is generated from native/java/com/rmsl/juce/ComponentPeerView.java with min sdk version 16 // See juce_core/native/java/README.txt on how to generate this byte-code. static const uint8 javaComponentPeerView[] = {31,139,8,8,174,115,161,94,0,3,106,97,118,97,67,111,109,112,111,110,101,110,116,80,101,101,114,86,105,101,119,46,100,101,120,0, 165,154,9,120,91,213,149,199,207,189,79,139,45,203,178,44,111,137,45,39,242,26,37,113,108,153,0,113,176,3,89,77,157,56,100,177, 146,18,59,52,60,75,207,182,18,249,61,69,146,237,4,232,16,150,38,41,100,90,104,3,221,82,186,165,25,74,51,109,153,161,148,73,75, 39,3,101,107,25,26,104,233,164,45,75,232,199,180,64,7,62,160,105,203,116,33,243,191,247,93,217,202,86,218,142,252,253,116,206, 59,247,220,253,222,115,175,100,197,141,29,158,200,252,139,40,84,84,16,62,178,99,227,93,78,119,55,171,63,246,210,255,110,45,251, 64,100,247,111,158,226,203,231,16,165,136,104,199,198,11,3,164,94,187,102,19,253,154,108,123,59,8,58,136,22,64,158,128,44,135, 204,186,137,12,200,242,2,34,13,178,171,136,232,238,25,68,7,32,127,82,69,116,28,156,0,239,128,63,130,83,128,79,35,114,129,66,80, 12,154,193,108,48,15,180,131,139,193,21,224,102,240,57,112,4,60,11,126,11,42,166,19,45,6,253,32,3,246,130,187,192,183,192,143, 192,187,160,172,26,101,1,3,236,6,247,131,231,65,97,13,81,7,216,5,190,13,94,0,60,72,84,15,86,128,45,32,13,238,4,223,1,79,131,147, 160,160,150,104,22,232,4,91,193,110,176,15,124,26,124,22,124,1,220,13,14,131,251,192,17,112,20,60,2,158,0,79,129,31,129,227, 224,5,240,11,240,26,120,29,188,13,222,1,127,6,12,227,230,2,30,224,3,245,96,1,88,6,214,128,1,48,12,50,96,23,216,11,238,0,159,3, 71,192,131,224,24,56,14,78,128,87,192,91,224,29,224,156,73,20,0,245,160,29,92,2,150,128,203,193,74,176,14,108,1,91,193,13,224, 54,240,105,112,8,220,7,254,29,252,24,188,8,222,4,239,2,119,136,200,15,106,65,27,184,12,68,65,12,100,192,237,224,19,224,179,224, 243,224,94,240,48,120,22,188,12,222,2,238,58,162,105,96,54,232,0,43,192,26,48,2,210,96,7,184,22,236,1,251,192,103,193,97,240, 32,120,28,252,4,188,0,94,3,39,193,41,80,80,79,84,7,34,96,1,232,6,189,32,10,54,131,45,192,0,38,200,130,107,192,63,130,47,130,251, 192,99,224,101,240,123,224,105,32,106,0,115,193,37,96,37,216,0,226,96,20,76,128,221,96,63,56,0,190,12,190,14,238,7,15,129, 39,192,147,224,77,224,107,196,250,5,213,96,14,232,0,235,128,14,44,240,97,240,121,240,32,248,62,248,41,248,111,240,91,160,53,97, 254,64,61,104,7,171,192,58,176,9,232,96,24,36,65,26,92,7,174,7,187,193,71,193,29,224,16,184,23,60,12,126,8,158,1,207,130,159, 130,231,155,236,189,235,4,216,206,228,3,37,192,15,74,129,8,6,101,100,239,247,10,80,9,176,141,9,219,145,176,221,8,91,139,106,68, 108,0,88,198,132,229,70,88,30,132,233,37,76,7,97,24,9,221,39,116,131,80,21,53,131,89,32,12,16,94,8,97,135,230,130,22,48,15, 180,130,54,16,81,49,231,2,48,31,92,8,46,2,29,224,114,176,26,92,1,214,128,181,100,247,33,247,114,40,121,115,165,221,47,166,158, 93,74,23,118,209,87,174,236,5,74,223,7,187,71,249,137,151,87,165,237,87,118,159,178,123,212,184,228,244,138,60,127,49,46,7,42, 109,93,140,201,65,149,183,78,249,20,169,177,16,109,40,86,227,113,88,249,11,253,62,229,31,86,254,197,106,140,190,83,105,247,125, 174,178,47,84,186,40,231,18,165,127,15,122,167,210,143,65,239,82,250,113,232,139,148,254,10,244,75,149,126,18,250,101,185,50, 49,169,139,149,94,0,125,169,210,253,121,246,105,121,122,8,250,114,165,135,243,236,23,230,233,93,121,250,242,188,50,123,243,236, 81,232,203,148,190,57,207,158,173,156,210,197,24,46,81,122,60,175,156,100,158,191,24,183,21,185,188,176,119,43,253,186,60,159, 125,121,250,254,42,123,29,181,168,241,124,159,210,15,192,222,163,244,131,208,87,42,253,27,208,123,149,254,0,244,85,74,63,154, 103,127,60,207,126,172,74,204,41,163,171,200,150,63,151,67,28,162,43,149,252,168,148,140,62,166,228,126,37,239,80,242,78,37,63, 161,252,63,79,98,175,181,208,231,164,172,161,159,146,216,119,65,58,174,228,75,82,86,211,203,36,214,29,167,219,164,172,161,187, 164,108,161,111,75,89,68,223,149,235,175,142,46,38,177,55,106,233,33,18,235,221,69,163,82,250,233,26,200,66,236,120,38,229,60, 122,132,196,122,172,147,207,69,202,94,132,221,243,168,236,151,253,92,130,250,146,82,150,146,169,158,175,21,107,71,217,253,216, 145,219,213,243,152,148,26,141,147,29,99,38,148,220,33,37,163,93,74,222,64,98,143,113,74,75,89,79,215,147,136,67,51,100,125, 101,136,10,223,148,178,157,238,151,178,130,254,141,196,62,108,166,126,37,31,38,17,171,154,164,255,116,68,144,143,72,217,64,79, 72,121,17,253,72,142,227,44,153,94,141,18,238,147,227,55,91,62,215,192,190,78,201,245,82,122,169,79,202,50,250,177,146,207,202, 241,156,41,253,131,24,201,168,148,97,218,32,101,25,109,86,82,151,50,34,239,73,65,212,180,77,74,151,188,83,5,85,255,130,136,122, 25,41,11,105,167,148,30,186,78,165,127,80,202,2,250,7,41,237,113,8,162,103,55,41,121,179,146,31,146,114,26,237,86,114,143,178, 239,149,178,138,62,172,228,45,74,222,42,229,116,218,39,101,27,125,70,201,3,82,6,233,30,181,126,190,170,228,97,37,255,89,165,127, 77,61,127,93,201,111,168,245,117,175,148,33,250,23,41,155,232,95,165,180,231,43,168,230,75,60,127,75,173,203,7,164,180,231, 47,136,40,127,68,202,185,244,152,146,143,75,217,72,63,144,178,156,254,83,202,57,244,148,122,254,161,242,59,166,228,211,42,253, 25,213,255,95,144,136,189,1,202,74,121,49,125,90,174,127,31,157,32,17,111,237,245,219,140,40,107,145,136,185,26,13,74,201,233, 75,36,226,110,9,125,138,236,51,142,200,142,207,34,46,137,179,98,57,228,199,85,144,174,81,107,184,89,249,137,244,40,210,15,169, 116,113,14,148,146,125,142,94,167,242,199,33,159,10,79,249,111,129,62,20,182,207,177,20,228,4,184,33,108,159,87,183,72,59,151, 250,137,38,177,47,113,31,12,20,81,202,127,53,108,1,218,236,247,200,179,169,0,79,34,255,171,240,25,16,245,185,202,169,158,123, 225,87,128,220,209,76,17,69,231,123,201,244,95,0,47,47,11,208,66,214,53,101,13,93,140,221,49,229,19,129,143,71,91,143,163,106, 125,19,163,123,163,183,147,230,184,232,234,106,218,144,241,80,135,86,73,1,109,51,180,156,127,52,91,68,219,253,77,216,231,94,199, 118,255,108,200,34,199,246,200,28,90,230,20,254,11,53,55,45,184,218,73,129,50,145,199,135,186,42,48,23,166,191,28,237,61,179, 142,240,83,226,252,214,228,152,248,154,237,187,200,64,192,171,250,90,143,185,72,133,66,24,237,1,191,143,6,202,138,101,191,153, 252,195,221,163,217,62,251,83,126,49,19,190,73,123,243,164,125,150,180,115,117,35,104,109,182,199,59,234,47,150,243,163,193, 46,234,189,184,217,62,143,163,161,98,180,82,220,62,208,195,58,209,238,106,212,236,155,244,91,116,94,191,26,233,231,67,92,16,61, 89,14,63,177,238,3,174,64,69,42,84,73,95,161,122,135,152,61,23,90,53,176,31,209,205,81,67,41,92,88,247,23,14,236,247,227,83, 150,19,37,124,128,14,146,199,209,225,184,138,102,122,196,51,110,228,212,127,160,4,90,63,37,104,243,103,16,105,67,125,180,9,239, 81,249,190,1,43,181,30,43,35,229,23,61,42,115,148,83,195,146,121,212,204,68,28,51,67,14,180,39,42,106,114,122,48,126,78,18, 37,186,17,179,2,154,233,215,145,203,235,168,118,126,159,2,205,13,67,109,20,112,15,22,148,209,234,2,151,59,80,21,44,40,146,154, 25,185,138,162,46,175,214,161,149,83,128,7,26,27,150,71,40,224,220,238,223,130,222,121,93,171,93,14,103,160,34,32,165,25,137, 211,199,29,24,3,63,230,22,229,206,116,216,173,223,79,225,47,20,59,194,39,193,219,224,77,240,51,112,28,83,46,239,150,83,175,93, 151,209,223,244,124,230,203,78,23,231,118,37,226,145,65,246,121,194,181,134,155,89,253,141,108,246,46,198,103,237,101,77,187, 153,61,223,226,117,143,90,7,125,161,18,185,143,197,250,19,207,247,230,214,77,164,139,234,52,49,155,246,254,58,162,214,101,223, 226,18,170,228,242,158,202,23,34,197,39,45,169,200,66,114,176,240,31,166,202,127,168,217,190,135,138,187,115,63,234,240,169, 58,196,235,241,102,123,255,7,252,37,147,235,242,25,213,158,13,254,82,89,15,87,235,248,120,179,125,55,52,253,23,138,157,131,59, 160,67,230,11,80,248,93,77,149,247,66,179,29,51,124,50,159,125,195,253,101,158,205,5,155,240,124,253,61,250,176,64,245,33,231, 255,187,247,240,239,152,236,179,221,142,83,231,104,135,123,214,217,54,95,158,205,161,234,170,152,101,223,151,3,76,68,222,129,8, 39,91,106,180,169,29,81,228,205,77,17,55,109,138,184,148,181,16,235,7,55,118,255,166,136,3,233,5,216,5,149,104,15,206,32,86, 170,250,43,198,190,113,150,29,131,207,221,254,232,210,0,165,214,47,38,199,186,240,59,226,179,129,38,231,189,229,188,121,230,175, 56,117,74,246,123,113,43,57,116,145,167,16,118,81,207,194,89,246,103,151,128,191,111,16,185,80,76,59,227,142,133,12,51,133, 241,107,113,139,207,78,34,197,244,23,33,94,123,88,106,221,37,212,156,9,255,198,138,84,209,120,129,135,194,111,152,254,185,104, 117,248,53,49,72,118,59,114,159,181,196,103,142,98,133,7,41,162,190,190,89,246,231,166,0,155,172,143,163,62,228,44,97,11,221, 133,168,167,16,109,243,240,64,195,5,23,184,201,90,60,141,198,63,233,97,225,183,77,156,25,216,247,188,131,191,126,42,167,155,161, 65,212,225,145,237,75,173,69,187,180,64,105,248,121,123,60,68,93,163,179,236,207,58,167,143,135,221,51,97,19,125,114,161,174, 212,250,78,140,100,192,31,254,173,125,183,20,175,107,242,230,185,144,156,178,188,189,106,124,173,43,167,83,116,60,191,212,14, 212,105,175,171,205,88,87,246,103,82,46,63,139,125,10,121,130,40,168,239,105,120,107,98,116,153,38,71,151,149,48,211,239,69,249, 158,66,211,47,206,133,34,247,179,183,159,162,185,236,119,114,116,194,111,245,61,131,157,194,76,236,191,25,136,172,166,95,68,104, 143,211,196,30,131,116,185,159,30,47,88,36,78,211,210,240,115,239,237,121,153,237,249,216,123,123,94,10,79,211,47,206,2,79, 81,160,116,65,205,28,10,212,53,4,91,17,19,219,113,151,9,84,95,116,164,142,68,41,162,140,175,137,50,66,1,33,89,192,185,220,233, 117,222,184,225,209,10,51,84,102,91,42,151,187,188,174,27,135,30,173,204,149,123,220,131,153,60,129,118,220,84,206,232,20,209, 55,111,127,201,195,10,22,122,166,209,95,219,131,217,52,116,42,191,61,127,79,75,68,73,225,159,255,237,45,88,164,90,208,244,255, 110,193,34,217,2,76,51,115,203,181,38,214,150,136,13,109,74,138,152,34,238,247,25,185,246,184,60,147,75,194,246,119,13,104,35, 78,64,55,86,127,181,246,36,5,202,27,150,227,4,116,14,186,112,2,202,211,236,42,186,192,225,101,11,81,178,15,251,46,252,46,248,83, 32,208,80,143,243,79,19,231,95,1,206,184,213,14,174,137,115,111,59,15,191,81,204,195,255,3,94,3,175,136,245,94,138,182,137, 251,161,87,68,34,62,171,178,105,154,214,16,174,111,153,61,39,47,6,46,12,79,237,13,77,89,151,132,237,123,94,7,119,99,127,153,161, 43,225,225,163,192,226,240,31,69,255,236,56,185,50,108,127,55,98,250,219,228,141,174,154,127,18,158,28,177,211,139,79,38,211, 169,3,145,195,244,199,176,67,61,108,17,43,195,104,155,145,153,20,65,143,47,146,254,102,100,6,249,29,209,118,63,238,110,13,178, 252,92,74,128,155,145,90,242,115,59,173,81,140,239,219,246,247,186,249,175,187,207,120,126,224,140,103,209,167,114,178,207,183, 82,180,130,41,155,253,153,201,150,5,74,86,41,89,163,252,155,17,69,197,115,88,61,135,49,155,14,202,221,245,236,243,144,171,185, 206,157,155,92,205,117,238,188,180,117,183,252,206,133,75,90,242,236,66,22,203,103,135,170,219,165,210,92,240,227,202,230,86, 178,80,73,175,202,235,67,139,236,249,85,231,183,202,19,84,243,39,62,35,137,244,22,213,198,150,188,118,11,230,41,217,170,242,51, 117,183,16,178,100,210,86,162,234,178,243,249,39,235,82,247,90,209,214,174,132,153,200,94,74,149,203,172,209,148,101,26,102, 118,173,97,164,55,38,140,137,214,173,250,184,78,172,155,120,119,15,177,30,226,61,16,43,137,175,236,165,170,85,198,206,65,75,79, 199,151,39,50,163,137,76,166,55,145,201,26,166,145,38,214,75,188,23,174,189,189,164,245,226,173,178,87,55,227,105,43,17,111, 211,83,169,182,37,177,108,98,60,145,221,217,73,23,158,110,79,165,146,137,152,158,77,88,102,99,206,167,55,49,100,196,118,198,146, 198,50,61,153,28,212,99,219,50,157,52,253,124,185,242,147,98,150,137,182,100,219,150,9,185,35,155,159,52,156,214,83,35,137, 88,166,109,153,110,142,235,40,112,198,57,146,172,164,149,238,78,36,179,70,250,252,233,171,245,108,58,177,163,147,102,255,197, 244,211,138,154,118,182,235,90,61,97,162,125,85,103,167,172,55,98,72,40,155,76,176,50,109,75,199,204,120,210,232,164,242,124, 99,207,210,132,25,23,165,79,149,49,142,153,107,195,244,172,24,55,68,225,213,167,39,172,182,196,112,169,180,217,167,167,137,57, 111,92,99,118,91,177,177,204,178,17,221,28,54,114,211,154,223,148,73,215,252,46,77,26,47,79,91,99,169,78,186,248,236,148,104, 218,48,214,12,102,140,244,184,145,70,45,151,39,173,65,61,217,171,239,180,198,178,83,213,204,252,203,249,58,169,245,116,135,132, 153,26,203,142,26,217,17,43,222,182,84,207,24,61,226,25,19,111,98,252,228,178,104,58,191,255,138,120,34,107,165,123,204,33, 171,147,230,156,223,237,172,34,231,189,135,239,106,169,175,214,77,125,88,180,184,187,55,102,141,182,165,71,51,201,182,173,99,49, 163,237,172,109,214,120,158,189,212,120,122,207,23,254,189,229,116,82,221,123,101,237,164,250,222,184,158,28,79,108,107,211, 77,211,202,202,61,213,182,194,140,37,173,76,194,28,94,150,212,51,114,179,156,237,211,131,113,73,171,244,186,115,164,175,54,70,7, 149,131,145,17,43,70,196,148,182,36,22,87,27,150,88,186,207,216,62,102,152,49,44,235,210,252,20,187,188,250,60,83,79,50,105, 12,235,201,37,177,152,145,201,172,216,17,51,82,246,100,52,158,195,39,61,60,54,138,206,229,121,149,229,123,33,42,12,219,163,50, 101,188,194,234,27,139,141,216,51,151,151,47,144,231,178,102,112,171,220,148,181,121,182,62,35,54,150,70,172,58,79,150,62,4, 1,115,88,172,152,41,91,218,24,74,162,28,52,99,220,178,99,87,84,79,15,27,249,173,173,62,135,187,221,52,220,138,163,155,214,174, 32,111,254,210,32,182,145,248,198,30,114,110,236,193,11,234,74,114,109,92,217,211,221,189,146,28,144,61,226,93,132,227,141,43, 251,145,40,148,222,149,226,77,106,253,72,237,237,71,80,223,216,143,92,253,178,4,214,79,90,191,200,135,183,94,161,34,166,247,11, 69,4,246,1,28,7,3,61,20,24,56,123,190,202,6,206,49,92,30,93,78,89,99,36,18,153,212,219,243,244,11,242,244,249,121,250,133,208, 139,108,189,59,169,15,103,200,165,203,253,39,140,66,246,234,131,70,146,10,116,117,90,208,116,61,30,63,119,84,33,54,72,165,226, 0,89,58,150,205,90,230,218,52,138,52,226,228,26,180,240,56,10,41,3,43,185,98,242,76,32,119,76,134,190,56,57,113,246,232,105, 42,138,89,113,99,173,133,72,189,36,43,30,38,163,59,249,228,67,52,173,155,153,33,43,61,74,197,226,228,65,72,207,72,111,20,100,31, 64,40,200,26,195,179,35,158,24,26,34,102,144,211,16,225,151,188,67,83,129,54,78,133,88,3,75,236,30,86,8,117,234,108,83,231, 24,21,195,44,246,12,186,108,164,51,84,32,30,197,192,147,71,104,202,201,43,150,146,40,62,154,24,53,100,161,239,51,18,195,35,89, 42,131,218,171,86,220,26,179,47,134,5,100,202,116,123,101,81,9,84,217,110,236,86,217,92,239,148,161,39,78,110,60,173,215,39, 174,204,41,155,168,72,40,150,149,21,241,131,252,120,232,219,137,241,30,237,195,154,76,196,12,242,193,178,193,76,136,193,19,141, 150,245,159,25,206,101,151,54,38,50,137,193,68,82,204,161,200,243,126,28,104,214,68,212,218,134,230,5,39,159,165,83,210,64, 100,75,37,245,157,221,105,29,157,115,32,245,74,249,190,137,216,8,149,96,32,49,143,24,184,181,250,152,152,96,255,164,97,189,145, 65,68,152,180,44,157,92,11,84,108,91,16,57,151,91,19,88,91,147,143,27,82,84,62,249,32,163,234,251,18,241,56,218,164,170,89, 109,161,14,153,231,52,67,90,31,206,149,41,13,40,70,149,41,207,122,42,24,209,51,242,124,165,170,145,68,220,232,179,134,178,242, 204,232,78,91,163,118,79,225,2,199,168,152,75,199,136,149,201,18,75,144,7,115,185,70,6,135,12,105,137,209,81,42,17,87,182,132, 158,92,166,167,50,171,49,194,84,172,12,125,70,114,133,25,159,76,199,99,95,86,79,103,169,80,158,82,209,157,41,131,188,82,221,98, 159,88,228,74,32,14,109,51,80,69,166,199,204,100,117,196,98,42,72,100,214,164,116,4,102,100,203,168,145,39,247,54,99,231,50, 81,85,213,182,243,92,253,138,115,9,125,35,98,92,156,73,185,67,139,49,95,70,90,212,124,5,142,28,114,36,141,161,44,185,146,134,57, 156,29,33,151,106,5,51,201,97,138,57,117,155,198,196,21,114,114,173,100,124,68,190,79,80,169,101,230,46,133,203,210,134,158, 197,76,150,77,153,150,27,153,108,218,218,41,166,119,202,168,150,64,94,206,220,26,168,153,50,245,233,227,70,174,211,24,166,172, 145,239,47,199,237,244,34,250,178,86,42,5,83,21,246,164,108,199,25,87,3,114,89,38,86,192,4,21,91,249,151,40,242,89,167,197,37, 42,180,204,220,130,43,150,234,234,177,100,54,145,18,131,44,31,177,104,10,68,128,147,206,240,232,75,92,99,228,194,132,23,231,133, 133,163,74,238,113,84,104,207,147,219,150,248,48,137,44,75,178,89,132,7,103,74,46,56,79,74,79,195,83,110,82,103,74,198,37, 150,166,250,180,49,44,166,45,125,254,203,54,5,211,198,168,53,110,216,45,95,99,158,17,83,157,105,25,85,180,140,145,37,95,70,196, 159,201,171,46,121,241,44,251,175,139,133,83,149,255,212,99,183,94,174,89,145,45,239,194,36,179,245,230,22,11,77,195,211,57, 239,162,84,145,201,197,154,13,137,188,224,81,115,78,179,184,234,232,136,219,25,59,250,200,181,85,156,57,45,234,120,114,143,73, 187,77,239,79,36,147,87,88,89,57,147,222,12,214,114,46,2,32,35,158,38,247,44,156,197,26,177,219,133,115,30,201,88,32,83,143, 211,50,118,107,122,166,234,82,61,117,100,71,18,56,208,196,123,99,68,201,118,88,69,200,214,80,6,84,49,4,5,99,217,161,14,25,60, 217,56,57,199,245,164,152,105,41,214,12,145,67,92,62,169,68,188,231,175,143,66,97,136,90,27,50,6,249,199,207,12,183,158,241,169, 94,179,9,98,59,136,239,136,128,118,98,59,233,7,156,145,219,215,223,69,207,224,19,111,203,128,198,31,98,197,123,52,118,148,149, 205,212,40,193,91,119,252,126,107,23,43,45,77,116,241,76,109,23,29,225,156,94,102,110,31,191,100,19,191,124,98,30,125,139,179, 87,241,120,150,60,138,194,124,247,209,35,182,232,208,134,31,100,183,51,119,11,127,154,58,249,27,108,130,63,252,193,137,189,140, 59,61,75,230,117,181,118,117,93,58,160,81,220,115,157,198,140,214,174,67,117,154,246,101,54,151,85,85,68,102,104,252,139,140, 179,210,42,39,231,235,106,157,228,100,78,205,229,225,115,15,58,61,46,114,49,23,119,105,115,230,240,241,22,39,159,195,51,45,52, 223,174,122,62,127,149,189,38,148,63,136,142,221,18,164,52,196,42,58,166,241,87,216,175,133,253,102,97,167,71,53,241,254,59, 141,247,111,129,124,83,99,253,16,63,147,2,121,110,112,8,229,214,32,189,166,28,254,100,59,188,108,139,63,115,246,93,230,174,93, 181,106,94,255,170,254,86,186,150,93,45,115,29,208,248,139,236,35,168,227,214,154,121,116,19,231,119,177,109,238,218,61,60,80, 203,83,181,188,164,147,143,29,220,204,119,174,164,67,92,187,139,141,32,137,23,239,230,227,181,119,14,108,221,163,209,11,140,247, 211,1,59,143,111,79,40,120,39,221,161,57,245,47,177,231,216,35,236,3,168,114,159,230,248,21,187,137,221,195,190,130,242,23, 237,233,167,143,51,233,201,31,167,90,126,228,250,218,85,90,225,149,188,87,115,255,156,105,252,97,218,196,23,183,176,178,146,136 ,141,191,87,43,58,196,248,162,46,205,251,31,172,109,17,99,154,231,99,140,207,99,193,226,203,156,30,167,183,221,89,180,213,229, 105,101,101,149,252,218,206,46,151,119,17,171,173,16,246,211,141,188,155,213,250,232,171,26,251,37,26,16,210,216,127,97,146,2, 149,220,219,194,71,107,177,84,182,134,103,56,73,200,230,6,39,189,20,153,67,255,164,177,187,197,112,255,64,99,155,221,190,68, 144,126,197,216,243,48,124,79,163,253,172,186,117,235,170,29,87,79,223,67,188,150,189,200,166,213,240,25,124,163,131,31,98,85, 11,108,67,80,26,2,48,20,242,153,48,4,217,180,234,156,82,67,156,49,15,103,183,133,66,187,118,57,142,86,213,177,151,171,72,115, 145,247,182,16,86,11,175,191,97,151,227,240,116,182,55,244,156,120,59,41,222,246,85,51,126,16,60,89,77,142,146,233,37,156,201, 191,48,28,79,86,35,121,255,12,188,29,158,225,184,145,83,33,96,127,5,65,48,151,125,111,6,99,39,193,109,51,203,217,193,153,140, 125,7,156,0,39,193,222,16,99,15,128,87,192,159,192,109,117,140,29,4,239,128,195,245,240,3,199,26,144,167,145,57,222,1,251,154, 24,59,218,228,96,123,231,48,182,127,46,103,119,131,39,231,218,223,221,228,190,19,203,201,220,111,43,197,119,58,185,223,87,138, 239,128,114,191,177,116,208,212,239,44,197,119,72,185,223,90,230,190,167,18,191,183,212,252,182,46,190,155,99,33,251,183,69,71, 161,187,66,182,93,252,159,154,249,237,239,209,228,255,174,67,118,189,226,247,153,154,242,23,255,83,118,132,236,114,197,255, 161,73,229,149,255,223,246,219,109,21,191,5,253,63,31,222,169,74,68,42,0,0,0,0}; //============================================================================== #if JUCE_PUSH_NOTIFICATIONS && JUCE_MODULE_AVAILABLE_juce_gui_extra // Returns true if the intent was handled. extern bool juce_handleNotificationIntent (void*); extern void juce_firebaseDeviceNotificationsTokenRefreshed (void*); extern void juce_firebaseRemoteNotificationReceived (void*); extern void juce_firebaseRemoteMessagesDeleted(); extern void juce_firebaseRemoteMessageSent(void*); extern void juce_firebaseRemoteMessageSendError (void*, void*); #endif //============================================================================== #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ METHOD (create, "", "(II)V") DECLARE_JNI_CLASS (AndroidLayoutParams, "android/view/ViewGroup$LayoutParams") #undef JNI_CLASS_MEMBERS //============================================================================== #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ METHOD (addView, "addView", "(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V") \ METHOD (removeView, "removeView", "(Landroid/view/View;)V") \ METHOD (updateViewLayout, "updateViewLayout", "(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V") DECLARE_JNI_CLASS (AndroidViewManager, "android/view/ViewManager") #undef JNI_CLASS_MEMBERS //============================================================================== #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ METHOD (create, "", "(IIIIIII)V") \ FIELD (gravity, "gravity", "I") \ FIELD (windowAnimations, "windowAnimations", "I") DECLARE_JNI_CLASS (AndroidWindowManagerLayoutParams, "android/view/WindowManager$LayoutParams") #undef JNI_CLASS_MEMBERS //============================================================================== #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ METHOD (getDecorView, "getDecorView", "()Landroid/view/View;") \ METHOD (setFlags, "setFlags", "(II)V") \ METHOD (clearFlags, "clearFlags", "(I)V") DECLARE_JNI_CLASS (AndroidWindow, "android/view/Window") #undef JNI_CLASS_MEMBERS namespace { enum { SYSTEM_UI_FLAG_VISIBLE = 0, SYSTEM_UI_FLAG_LOW_PROFILE = 1, SYSTEM_UI_FLAG_HIDE_NAVIGATION = 2, SYSTEM_UI_FLAG_FULLSCREEN = 4, SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION = 512, SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN = 1024, SYSTEM_UI_FLAG_IMMERSIVE = 2048, SYSTEM_UI_FLAG_IMMERSIVE_STICKY = 4096 }; constexpr int fullScreenFlags = SYSTEM_UI_FLAG_HIDE_NAVIGATION | SYSTEM_UI_FLAG_FULLSCREEN | SYSTEM_UI_FLAG_IMMERSIVE_STICKY; constexpr int FLAG_NOT_FOCUSABLE = 0x8; } //============================================================================== class AndroidComponentPeer : public ComponentPeer, private Timer { public: AndroidComponentPeer (Component& comp, int windowStyleFlags, void* nativeViewHandle) : ComponentPeer (comp, windowStyleFlags), fullScreen (false), navBarsHidden (false), sizeAllocated (0), scale ((float) Desktop::getInstance().getDisplays().getMainDisplay().scale) { auto* env = getEnv(); // NB: must not put this in the initialiser list, as it invokes a callback, // which will fail if the peer is only half-constructed. view = GlobalRef (LocalRef (env->NewObject (ComponentPeerView, ComponentPeerView.create, getAppContext().get(), (jboolean) component.isOpaque(), (jlong) this))); if (nativeViewHandle != nullptr) { viewGroupIsWindow = false; // we don't know if the user is holding on to a local ref to this, so // explicitly create a new one auto nativeView = LocalRef(env->NewLocalRef(static_cast (nativeViewHandle))); if (env->IsInstanceOf (nativeView.get(), AndroidActivity)) { viewGroup = GlobalRef (nativeView); env->CallVoidMethod (viewGroup.get(), AndroidActivity.setContentView, view.get()); } else if (env->IsInstanceOf (nativeView.get(), AndroidViewGroup)) { viewGroup = GlobalRef (nativeView); LocalRef layoutParams (env->NewObject (AndroidLayoutParams, AndroidLayoutParams.create, -2, -2)); env->CallVoidMethod (view.get(), AndroidView.setLayoutParams, layoutParams.get()); env->CallVoidMethod ((jobject) viewGroup.get(), AndroidViewGroup.addView, view.get()); } else { // the native handle you passed as a second argument to Component::addToDesktop must // either be an Activity or a ViewGroup jassertfalse; } } else { viewGroupIsWindow = true; LocalRef viewLayoutParams (env->NewObject (AndroidLayoutParams, AndroidLayoutParams.create, -2, -2)); env->CallVoidMethod (view.get(), AndroidView.setLayoutParams, viewLayoutParams.get()); Rectangle physicalBounds = comp.getBoundsInParent() * scale; view.callVoidMethod (AndroidView.layout, physicalBounds.getX(), physicalBounds.getY(), physicalBounds.getRight(), physicalBounds.getBottom()); LocalRef windowLayoutParams (env->NewObject (AndroidWindowManagerLayoutParams, AndroidWindowManagerLayoutParams.create, physicalBounds.getWidth(), physicalBounds.getHeight(), physicalBounds.getX(), physicalBounds.getY(), TYPE_APPLICATION, FLAG_NOT_TOUCH_MODAL | FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_NO_LIMITS | FLAG_NOT_FOCUSABLE, component.isOpaque() ? PIXEL_FORMAT_OPAQUE : PIXEL_FORMAT_TRANSPARENT)); env->SetIntField (windowLayoutParams.get(), AndroidWindowManagerLayoutParams.gravity, GRAVITY_LEFT | GRAVITY_TOP); env->SetIntField (windowLayoutParams.get(), AndroidWindowManagerLayoutParams.windowAnimations, 0x01030000 /* android.R.style.Animation */); if (Desktop::getInstance().getKioskModeComponent() != nullptr) setNavBarsHidden (true); LocalRef activity (getCurrentActivity()); if (activity == nullptr) activity = getMainActivity(); viewGroup = GlobalRef (LocalRef (env->CallObjectMethod (activity.get(), AndroidContext.getSystemService, javaString ("window").get()))); env->CallVoidMethod (viewGroup.get(), AndroidViewManager.addView, view.get(), windowLayoutParams.get()); } if (isFocused()) handleFocusGain(); } ~AndroidComponentPeer() override { auto* env = getEnv(); env->CallVoidMethod (view, ComponentPeerView.clear); frontWindow = nullptr; if (MessageManager::getInstance()->isThisTheMessageThread()) { if (env->IsInstanceOf (viewGroup.get(), AndroidActivity)) env->CallVoidMethod (viewGroup.get(), AndroidActivity.setContentView, nullptr); else env->CallVoidMethod (viewGroup.get(), AndroidViewManager.removeView, view.get()); } else { struct ViewDeleter : public CallbackMessage { ViewDeleter (const GlobalRef& view_, const GlobalRef& viewGroup_) : view (view_), group (viewGroup_) {} void messageCallback() override { auto* callbackEnv = getEnv(); if (callbackEnv->IsInstanceOf (group.get(), AndroidActivity)) callbackEnv->CallVoidMethod (group.get(), AndroidActivity.setContentView, nullptr); else callbackEnv->CallVoidMethod (group.get(), AndroidViewManager.removeView, view.get()); } private: GlobalRef view, group; }; (new ViewDeleter (view, viewGroup))->post(); } } void* getNativeHandle() const override { return (void*) view.get(); } void setVisible (bool shouldBeVisible) override { if (MessageManager::getInstance()->isThisTheMessageThread()) { view.callVoidMethod (ComponentPeerView.setVisible, shouldBeVisible); } else { struct VisibilityChanger : public CallbackMessage { VisibilityChanger (const GlobalRef& view_, bool shouldBeVisible_) : view (view_), shouldBeVisible (shouldBeVisible_) {} void messageCallback() override { view.callVoidMethod (ComponentPeerView.setVisible, shouldBeVisible); } GlobalRef view; bool shouldBeVisible; }; (new VisibilityChanger (view, shouldBeVisible))->post(); } } void setTitle (const String& title) override { view.callVoidMethod (ComponentPeerView.setViewName, javaString (title).get()); } void setBounds (const Rectangle& userRect, bool isNowFullScreen) override { Rectangle r = (userRect.toFloat() * scale).toNearestInt(); if (MessageManager::getInstance()->isThisTheMessageThread()) { auto* env = getEnv(); fullScreen = isNowFullScreen; { view.callVoidMethod (AndroidView.layout, r.getX(), r.getY(), r.getRight(), r.getBottom()); if (viewGroup != nullptr && viewGroupIsWindow) { LocalRef windowLayoutParams (env->NewObject (AndroidWindowManagerLayoutParams, AndroidWindowManagerLayoutParams.create, r.getWidth(), r.getHeight(), r.getX(), r.getY(), TYPE_APPLICATION, FLAG_NOT_TOUCH_MODAL | FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_NO_LIMITS, component.isOpaque() ? PIXEL_FORMAT_OPAQUE : PIXEL_FORMAT_TRANSPARENT)); env->SetIntField (windowLayoutParams.get(), AndroidWindowManagerLayoutParams.gravity, 0x3 /* LEFT */ | 0x30 /* TOP */); env->CallVoidMethod (viewGroup.get(), AndroidViewManager.updateViewLayout, view.get(), windowLayoutParams.get()); } } } else { class ViewMover : public CallbackMessage { public: ViewMover (const GlobalRef& v, Rectangle boundsToUse) : view (v), bounds (boundsToUse) {} void messageCallback() override { view.callVoidMethod (AndroidView.layout, bounds.getX(), bounds.getY(), bounds.getRight(), bounds.getBottom()); } private: GlobalRef view; Rectangle bounds; }; (new ViewMover (view, r))->post(); } } Rectangle getBounds() const override { Rectangle r (view.callIntMethod (AndroidView.getLeft), view.callIntMethod (AndroidView.getTop), view.callIntMethod (AndroidView.getWidth), view.callIntMethod (AndroidView.getHeight)); return r / scale; } void handleScreenSizeChange() override { ComponentPeer::handleScreenSizeChange(); if (isFullScreen()) setFullScreen (true); } Point getScreenPosition() const { auto* env = getEnv(); LocalRef position (env->NewIntArray (2)); env->CallVoidMethod (view.get(), AndroidView.getLocationOnScreen, position.get()); jint* const screenPosition = env->GetIntArrayElements (position.get(), nullptr); Point pos (screenPosition[0], screenPosition[1]); env->ReleaseIntArrayElements (position.get(), screenPosition, 0); return pos; } Point localToGlobal (Point relativePosition) override { return relativePosition + (getScreenPosition().toFloat() / scale); } using ComponentPeer::localToGlobal; Point globalToLocal (Point screenPosition) override { return screenPosition - (getScreenPosition().toFloat() / scale); } using ComponentPeer::globalToLocal; void setMinimised (bool /*shouldBeMinimised*/) override { // n/a } bool isMinimised() const override { return false; } bool shouldNavBarsBeHidden (bool shouldBeFullScreen) const { if (shouldBeFullScreen) if (Component* kiosk = Desktop::getInstance().getKioskModeComponent()) if (kiosk->getPeer() == this) return true; return false; } void setNavBarsHidden (bool hidden) { view.callVoidMethod (ComponentPeerView.setSystemUiVisibilityCompat, hidden ? (jint) (fullScreenFlags) : (jint) (SYSTEM_UI_FLAG_VISIBLE)); navBarsHidden = hidden; } void setFullScreen (bool shouldBeFullScreen) override { // updating the nav bar visibility is a bit odd on Android - need to wait for if (shouldNavBarsBeHidden (shouldBeFullScreen)) { if (! isTimerRunning()) { startTimer (500); } } else { setNavBarsHidden (false); } Rectangle r (shouldBeFullScreen ? Desktop::getInstance().getDisplays().getMainDisplay().userArea : lastNonFullscreenBounds); if ((! shouldBeFullScreen) && r.isEmpty()) r = getBounds(); // (can't call the component's setBounds method because that'll reset our fullscreen flag) if (! r.isEmpty()) setBounds (r, shouldBeFullScreen); component.repaint(); } bool isFullScreen() const override { return fullScreen; } void timerCallback() override { setNavBarsHidden (shouldNavBarsBeHidden (fullScreen)); setFullScreen (fullScreen); stopTimer(); } void setIcon (const Image& /*newIcon*/) override { // n/a } bool contains (Point localPos, bool trueIfInAChildWindow) const override { return isPositiveAndBelow (localPos.x, component.getWidth()) && isPositiveAndBelow (localPos.y, component.getHeight()) && ((! trueIfInAChildWindow) || view.callBooleanMethod (ComponentPeerView.containsPoint, localPos.x * scale, localPos.y * scale)); } BorderSize getFrameSize() const override { // TODO return BorderSize(); } bool setAlwaysOnTop (bool /*alwaysOnTop*/) override { // TODO return false; } void toFront (bool makeActive) override { // Avoid calling bringToFront excessively: it's very slow if (frontWindow != this) { view.callVoidMethod (AndroidView.bringToFront); frontWindow = this; } if (makeActive) grabFocus(); handleBroughtToFront(); } void toBehind (ComponentPeer*) override { // TODO } //============================================================================== void handleMouseDownCallback (int index, Point sysPos, int64 time) { lastMousePos = sysPos / scale; Point pos = globalToLocal (lastMousePos); // this forces a mouse-enter/up event, in case for some reason we didn't get a mouse-up before. handleMouseEvent (MouseInputSource::InputSourceType::touch, pos, ModifierKeys::currentModifiers.withoutMouseButtons(), MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, time, {}, index); if (isValidPeer (this)) handleMouseDragCallback (index, sysPos, time); } void handleMouseDragCallback (int index, Point sysPos, int64 time) { lastMousePos = sysPos / scale; Point pos = globalToLocal (lastMousePos); jassert (index < 64); touchesDown = (touchesDown | (1 << (index & 63))); ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier); handleMouseEvent (MouseInputSource::InputSourceType::touch, pos, ModifierKeys::currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier), MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, time, {}, index); } void handleMouseUpCallback (int index, Point sysPos, int64 time) { lastMousePos = sysPos / scale; Point pos = globalToLocal (lastMousePos); jassert (index < 64); touchesDown = (touchesDown & ~(1 << (index & 63))); if (touchesDown == 0) ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withoutMouseButtons(); handleMouseEvent (MouseInputSource::InputSourceType::touch, pos, ModifierKeys::currentModifiers.withoutMouseButtons(), MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, time, {}, index); } void handleKeyDownCallback (int k, int kc) { handleKeyPress (k, static_cast (kc)); } void handleKeyUpCallback (int /*k*/, int /*kc*/) { } void handleBackButtonCallback() { bool handled = false; if (auto* app = JUCEApplicationBase::getInstance()) handled = app->backButtonPressed(); if (Component* kiosk = Desktop::getInstance().getKioskModeComponent()) if (kiosk->getPeer() == this) setNavBarsHidden (navBarsHidden); if (! handled) { auto* env = getEnv(); LocalRef activity (getCurrentActivity()); if (activity != nullptr) { jmethodID finishMethod = env->GetMethodID (AndroidActivity, "finish", "()V"); if (finishMethod != nullptr) env->CallVoidMethod (activity.get(), finishMethod); } } } void handleKeyboardHiddenCallback() { Component::unfocusAllComponents(); } void handleAppPausedCallback() {} void handleAppResumedCallback() { if (Component* kiosk = Desktop::getInstance().getKioskModeComponent()) if (kiosk->getPeer() == this) setNavBarsHidden (navBarsHidden); } //============================================================================== bool isFocused() const override { if (view != nullptr) return view.callBooleanMethod (AndroidView.hasFocus); return false; } void grabFocus() override { if (view != nullptr) view.callBooleanMethod (AndroidView.requestFocus); } void handleFocusChangeCallback (bool hasFocus) { if (isFullScreen()) setFullScreen (true); if (hasFocus) handleFocusGain(); else handleFocusLoss(); } static const char* getVirtualKeyboardType (TextInputTarget::VirtualKeyboardType type) noexcept { switch (type) { case TextInputTarget::textKeyboard: return "text"; case TextInputTarget::numericKeyboard: return "number"; case TextInputTarget::decimalKeyboard: return "numberDecimal"; case TextInputTarget::urlKeyboard: return "textUri"; case TextInputTarget::emailAddressKeyboard: return "textEmailAddress"; case TextInputTarget::phoneNumberKeyboard: return "phone"; default: jassertfalse; break; } return "text"; } void textInputRequired (Point, TextInputTarget& target) override { view.callVoidMethod (ComponentPeerView.showKeyboard, javaString (getVirtualKeyboardType (target.getKeyboardType())).get()); } void dismissPendingTextInput() override { view.callVoidMethod (ComponentPeerView.showKeyboard, javaString ("").get()); // updating the nav bar visibility is a bit odd on Android - need to wait for if (! isTimerRunning()) hideNavBarDelayed(); } void hideNavBarDelayed() { startTimer (500); } //============================================================================== void handlePaintCallback (jobject canvas, jobject paint) { auto* env = getEnv(); jobject rect = env->CallObjectMethod (canvas, AndroidCanvas.getClipBounds); const int left = env->GetIntField (rect, AndroidRect.left); const int top = env->GetIntField (rect, AndroidRect.top); const int right = env->GetIntField (rect, AndroidRect.right); const int bottom = env->GetIntField (rect, AndroidRect.bottom); env->DeleteLocalRef (rect); const Rectangle clip (left, top, right - left, bottom - top); const int sizeNeeded = clip.getWidth() * clip.getHeight(); if (sizeAllocated < sizeNeeded) { buffer.clear(); sizeAllocated = sizeNeeded; buffer = GlobalRef (LocalRef ((jobject) env->NewIntArray (sizeNeeded))); } else if (sizeNeeded == 0) { return; } if (jint* dest = env->GetIntArrayElements ((jintArray) buffer.get(), nullptr)) { { Image temp (new PreallocatedImage (clip.getWidth(), clip.getHeight(), dest, ! component.isOpaque())); { LowLevelGraphicsSoftwareRenderer g (temp); g.setOrigin (-clip.getPosition()); g.addTransform (AffineTransform::scale (scale)); handlePaint (g); } } env->ReleaseIntArrayElements ((jintArray) buffer.get(), dest, 0); env->CallVoidMethod (canvas, AndroidCanvas.drawBitmap, (jintArray) buffer.get(), 0, clip.getWidth(), (jfloat) clip.getX(), (jfloat) clip.getY(), clip.getWidth(), clip.getHeight(), true, paint); } } void repaint (const Rectangle& userArea) override { Rectangle area = userArea * scale; if (MessageManager::getInstance()->isThisTheMessageThread()) { view.callVoidMethod (AndroidView.invalidate, area.getX(), area.getY(), area.getRight(), area.getBottom()); } else { struct ViewRepainter : public CallbackMessage { ViewRepainter (const GlobalRef& view_, const Rectangle& area_) : view (view_), area (area_) {} void messageCallback() override { view.callVoidMethod (AndroidView.invalidate, area.getX(), area.getY(), area.getRight(), area.getBottom()); } private: GlobalRef view; const Rectangle area; }; (new ViewRepainter (view, area))->post(); } } void performAnyPendingRepaintsNow() override { // TODO } void setAlpha (float /*newAlpha*/) override { // TODO } StringArray getAvailableRenderingEngines() override { return StringArray ("Software Renderer"); } //============================================================================== static Point lastMousePos; static int64 touchesDown; //============================================================================== struct StartupActivityCallbackListener : ActivityLifecycleCallbacks { void onActivityStarted (jobject /*activity*/) override { auto* env = getEnv(); LocalRef appContext (getAppContext()); if (appContext.get() != nullptr) { env->CallVoidMethod (appContext.get(), AndroidApplication.unregisterActivityLifecycleCallbacks, activityCallbackListener.get()); clear(); activityCallbackListener.clear(); const_cast (Desktop::getInstance().getDisplays()).refresh(); } } }; private: //============================================================================== GlobalRef view, viewGroup; bool viewGroupIsWindow = false; GlobalRef buffer; bool fullScreen; bool navBarsHidden; int sizeAllocated; float scale; //============================================================================== #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ METHOD (create, "", "(Landroid/content/Context;ZJ)V") \ METHOD (clear, "clear", "()V") \ METHOD (setViewName, "setViewName", "(Ljava/lang/String;)V") \ METHOD (setVisible, "setVisible", "(Z)V") \ METHOD (isVisible, "isVisible", "()Z") \ METHOD (containsPoint, "containsPoint", "(II)Z") \ METHOD (showKeyboard, "showKeyboard", "(Ljava/lang/String;)V") \ METHOD (setSystemUiVisibilityCompat, "setSystemUiVisibilityCompat", "(I)V") \ CALLBACK (handlePaintJni, "handlePaint", "(JLandroid/graphics/Canvas;Landroid/graphics/Paint;)V") \ CALLBACK (handleMouseDownJni, "handleMouseDown", "(JIFFJ)V") \ CALLBACK (handleMouseDragJni, "handleMouseDrag", "(JIFFJ)V") \ CALLBACK (handleMouseUpJni, "handleMouseUp", "(JIFFJ)V") \ CALLBACK (handleKeyDownJni, "handleKeyDown", "(JII)V") \ CALLBACK (handleKeyUpJni, "handleKeyUp", "(JII)V") \ CALLBACK (handleBackButtonJni, "handleBackButton", "(J)V") \ CALLBACK (handleKeyboardHiddenJni, "handleKeyboardHidden", "(J)V") \ CALLBACK (viewSizeChangedJni, "viewSizeChanged", "(J)V") \ CALLBACK (focusChangedJni, "focusChanged", "(JZ)V") \ CALLBACK (handleAppPausedJni, "handleAppPaused", "(J)V") \ CALLBACK (handleAppResumedJni, "handleAppResumed", "(J)V") \ DECLARE_JNI_CLASS_WITH_BYTECODE (ComponentPeerView, "com/rmsl/juce/ComponentPeerView", 16, javaComponentPeerView, sizeof (javaComponentPeerView)) #undef JNI_CLASS_MEMBERS static void JNICALL handlePaintJni (JNIEnv*, jobject /*view*/, jlong host, jobject canvas, jobject paint) { if (auto* myself = reinterpret_cast (host)) myself->handlePaintCallback (canvas, paint); } static void JNICALL handleMouseDownJni (JNIEnv*, jobject /*view*/, jlong host, jint i, jfloat x, jfloat y, jlong time) { if (auto* myself = reinterpret_cast (host)) myself->handleMouseDownCallback (i, Point ((float) x, (float) y), (int64) time); } static void JNICALL handleMouseDragJni (JNIEnv*, jobject /*view*/, jlong host, jint i, jfloat x, jfloat y, jlong time) { if (auto* myself = reinterpret_cast (host)) myself->handleMouseDragCallback (i, Point ((float) x, (float) y), (int64) time); } static void JNICALL handleMouseUpJni (JNIEnv*, jobject /*view*/, jlong host, jint i, jfloat x, jfloat y, jlong time) { if (auto* myself = reinterpret_cast (host)) myself->handleMouseUpCallback (i, Point ((float) x, (float) y), (int64) time); } static void JNICALL viewSizeChangedJni (JNIEnv*, jobject /*view*/, jlong host) { if (auto* myself = reinterpret_cast (host)) myself->handleMovedOrResized(); } static void JNICALL focusChangedJni (JNIEnv*, jobject /*view*/, jlong host, jboolean hasFocus) { if (auto* myself = reinterpret_cast (host)) myself->handleFocusChangeCallback (hasFocus); } static void JNICALL handleKeyDownJni (JNIEnv*, jobject /*view*/, jlong host, jint k, jint kc) { if (auto* myself = reinterpret_cast (host)) myself->handleKeyDownCallback ((int) k, (int) kc); } static void JNICALL handleKeyUpJni (JNIEnv*, jobject /*view*/, jlong host, jint k, jint kc) { if (auto* myself = reinterpret_cast (host)) myself->handleKeyUpCallback ((int) k, (int) kc); } static void JNICALL handleBackButtonJni (JNIEnv*, jobject /*view*/, jlong host) { if (auto* myself = reinterpret_cast (host)) myself->handleBackButtonCallback(); } static void JNICALL handleKeyboardHiddenJni (JNIEnv*, jobject /*view*/, jlong host) { if (auto* myself = reinterpret_cast (host)) myself->handleKeyboardHiddenCallback(); } static void JNICALL handleAppPausedJni (JNIEnv*, jobject /*view*/, jlong host) { if (auto* myself = reinterpret_cast (host)) myself->handleAppPausedCallback(); } static void JNICALL handleAppResumedJni (JNIEnv*, jobject /*view*/, jlong host) { if (auto* myself = reinterpret_cast (host)) myself->handleAppResumedCallback(); } //============================================================================== friend class Displays; static AndroidComponentPeer* frontWindow; static GlobalRef activityCallbackListener; //============================================================================== static constexpr int GRAVITY_LEFT = 0x3, GRAVITY_TOP = 0x30; static constexpr int TYPE_APPLICATION = 0x2; static constexpr int FLAG_NOT_TOUCH_MODAL = 0x20, FLAG_LAYOUT_IN_SCREEN = 0x100, FLAG_LAYOUT_NO_LIMITS = 0x200; static constexpr int PIXEL_FORMAT_OPAQUE = -1, PIXEL_FORMAT_TRANSPARENT = -2; struct PreallocatedImage : public ImagePixelData { PreallocatedImage (int width_, int height_, jint* data_, bool hasAlpha_) : ImagePixelData (Image::ARGB, width_, height_), data (data_), hasAlpha (hasAlpha_) { if (hasAlpha_) zeromem (data_, static_cast (width * height) * sizeof (jint)); } ~PreallocatedImage() override { if (hasAlpha) { auto pix = (PixelARGB*) data; for (int i = width * height; --i >= 0;) { pix->unpremultiply(); ++pix; } } } std::unique_ptr createType() const override { return std::make_unique(); } std::unique_ptr createLowLevelContext() override { return std::make_unique (Image (this)); } void initialiseBitmapData (Image::BitmapData& bm, int x, int y, Image::BitmapData::ReadWriteMode /*mode*/) override { bm.lineStride = width * static_cast (sizeof (jint)); bm.pixelStride = static_cast (sizeof (jint)); bm.pixelFormat = Image::ARGB; bm.data = (uint8*) (data + x + y * width); } ImagePixelData::Ptr clone() override { auto s = new PreallocatedImage (width, height, nullptr, hasAlpha); s->allocatedData.malloc (sizeof (jint) * static_cast (width * height)); s->data = s->allocatedData; memcpy (s->data, data, sizeof (jint) * static_cast (width * height)); return s; } private: jint* data; HeapBlock allocatedData; bool hasAlpha; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PreallocatedImage) }; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AndroidComponentPeer) }; Point AndroidComponentPeer::lastMousePos; int64 AndroidComponentPeer::touchesDown = 0; AndroidComponentPeer* AndroidComponentPeer::frontWindow = nullptr; GlobalRef AndroidComponentPeer::activityCallbackListener; AndroidComponentPeer::ComponentPeerView_Class AndroidComponentPeer::ComponentPeerView; //============================================================================== ComponentPeer* Component::createNewPeer (int styleFlags, void* nativeWindow) { return new AndroidComponentPeer (*this, styleFlags, nativeWindow); } //============================================================================== bool Desktop::canUseSemiTransparentWindows() noexcept { return true; } double Desktop::getDefaultMasterScale() { return 1.0; } Desktop::DisplayOrientation Desktop::getCurrentOrientation() const { enum { ROTATION_0 = 0, ROTATION_90 = 1, ROTATION_180 = 2, ROTATION_270 = 3 }; JNIEnv* env = getEnv(); LocalRef windowServiceString (javaString ("window")); LocalRef windowManager = LocalRef (env->CallObjectMethod (getAppContext().get(), AndroidContext.getSystemService, windowServiceString.get())); if (windowManager.get() != nullptr) { LocalRef display = LocalRef (env->CallObjectMethod (windowManager, AndroidWindowManager.getDefaultDisplay)); if (display.get() != nullptr) { int rotation = env->CallIntMethod (display, AndroidDisplay.getRotation); switch (rotation) { case ROTATION_0: return upright; case ROTATION_90: return rotatedAntiClockwise; case ROTATION_180: return upsideDown; case ROTATION_270: return rotatedClockwise; } } } jassertfalse; return upright; } bool MouseInputSource::SourceList::addSource() { addSource (sources.size(), MouseInputSource::InputSourceType::touch); return true; } bool MouseInputSource::SourceList::canUseTouch() { return true; } Point MouseInputSource::getCurrentRawMousePosition() { return AndroidComponentPeer::lastMousePos; } void MouseInputSource::setRawMousePosition (Point) { // not needed } //============================================================================== bool KeyPress::isKeyCurrentlyDown (int /*keyCode*/) { // TODO return false; } JUCE_API void JUCE_CALLTYPE Process::hide() { auto* env = getEnv(); LocalRef currentActivity (getCurrentActivity().get()); if (env->CallBooleanMethod (currentActivity.get(), AndroidActivity.moveTaskToBack, true) == 0) { GlobalRef intent (LocalRef (env->NewObject (AndroidIntent, AndroidIntent.constructor))); env->CallObjectMethod (intent, AndroidIntent.setAction, javaString ("android.intent.action.MAIN") .get()); env->CallObjectMethod (intent, AndroidIntent.addCategory, javaString ("android.intent.category.HOME").get()); env->CallVoidMethod (currentActivity.get(), AndroidContext.startActivity, intent.get()); } } //============================================================================== // TODO JUCE_API bool JUCE_CALLTYPE Process::isForegroundProcess() { return true; } JUCE_API void JUCE_CALLTYPE Process::makeForegroundProcess() {} //============================================================================== #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ METHOD (show, "show", "()V") \ METHOD (getWindow, "getWindow", "()Landroid/view/Window;") DECLARE_JNI_CLASS (AndroidDialog, "android/app/Dialog") #undef JNI_CLASS_MEMBERS #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ METHOD (construct, "", "(Landroid/content/Context;)V") \ METHOD (create, "create", "()Landroid/app/AlertDialog;") \ METHOD (setTitle, "setTitle", "(Ljava/lang/CharSequence;)Landroid/app/AlertDialog$Builder;") \ METHOD (setMessage, "setMessage", "(Ljava/lang/CharSequence;)Landroid/app/AlertDialog$Builder;") \ METHOD (setCancelable, "setCancelable", "(Z)Landroid/app/AlertDialog$Builder;") \ METHOD (setOnCancelListener, "setOnCancelListener", "(Landroid/content/DialogInterface$OnCancelListener;)Landroid/app/AlertDialog$Builder;") \ METHOD (setPositiveButton, "setPositiveButton", "(Ljava/lang/CharSequence;Landroid/content/DialogInterface$OnClickListener;)Landroid/app/AlertDialog$Builder;") \ METHOD (setNegativeButton, "setNegativeButton", "(Ljava/lang/CharSequence;Landroid/content/DialogInterface$OnClickListener;)Landroid/app/AlertDialog$Builder;") \ METHOD (setNeutralButton, "setNeutralButton", "(Ljava/lang/CharSequence;Landroid/content/DialogInterface$OnClickListener;)Landroid/app/AlertDialog$Builder;") DECLARE_JNI_CLASS (AndroidAlertDialogBuilder, "android/app/AlertDialog$Builder") #undef JNI_CLASS_MEMBERS #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ METHOD (dismiss, "dismiss", "()V") DECLARE_JNI_CLASS (AndroidDialogInterface, "android/content/DialogInterface") #undef JNI_CLASS_MEMBERS #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ DECLARE_JNI_CLASS (AndroidDialogOnClickListener, "android/content/DialogInterface$OnClickListener") #undef JNI_CLASS_MEMBERS //============================================================================== class DialogListener : public juce::AndroidInterfaceImplementer { public: DialogListener (ModalComponentManager::Callback* callbackToUse, int resultToUse) : callback (callbackToUse), result (resultToUse) {} void onResult (jobject dialog) { auto* env = getEnv(); env->CallVoidMethod (dialog, AndroidDialogInterface.dismiss); if (callback != nullptr) callback->modalStateFinished (result); callback = nullptr; } private: jobject invoke (jobject proxy, jobject method, jobjectArray args) override { auto* env = getEnv(); auto methodName = juce::juceString ((jstring) env->CallObjectMethod (method, JavaMethod.getName)); if (methodName == "onCancel" || methodName == "onClick") { onResult (env->GetObjectArrayElement (args, 0)); return nullptr; } // invoke base class return AndroidInterfaceImplementer::invoke (proxy, method, args); } std::unique_ptr callback; int result; }; //============================================================================== static void createAndroidDialog (const String& title, const String& message, ModalComponentManager::Callback* callback, const String& positiveButton = {}, const String& negativeButton = {}, const String& neutralButton = {}) { auto* env = getEnv(); LocalRef builder (env->NewObject (AndroidAlertDialogBuilder, AndroidAlertDialogBuilder.construct, getMainActivity().get())); builder = LocalRef (env->CallObjectMethod (builder.get(), AndroidAlertDialogBuilder.setTitle, javaString (title).get())); builder = LocalRef (env->CallObjectMethod (builder.get(), AndroidAlertDialogBuilder.setMessage, javaString (message).get())); builder = LocalRef (env->CallObjectMethod (builder.get(), AndroidAlertDialogBuilder.setCancelable, true)); builder = LocalRef (env->CallObjectMethod (builder.get(), AndroidAlertDialogBuilder.setOnCancelListener, CreateJavaInterface (new DialogListener (callback, 0), "android/content/DialogInterface$OnCancelListener").get())); auto positiveButtonText = positiveButton.isEmpty() ? String ("OK") : positiveButton; builder = LocalRef (env->CallObjectMethod (builder.get(), AndroidAlertDialogBuilder.setPositiveButton, javaString (positiveButtonText).get(), CreateJavaInterface (new DialogListener (callback, positiveButton.isEmpty() ? 0 : 1), "android/content/DialogInterface$OnClickListener").get())); if (negativeButton.isNotEmpty()) builder = LocalRef (env->CallObjectMethod (builder.get(), AndroidAlertDialogBuilder.setNegativeButton, javaString (negativeButton).get(), CreateJavaInterface (new DialogListener (callback, neutralButton.isEmpty() ? 0 : 2), "android/content/DialogInterface$OnClickListener").get())); if (neutralButton.isNotEmpty()) builder = LocalRef (env->CallObjectMethod (builder.get(), AndroidAlertDialogBuilder.setNegativeButton, javaString (neutralButton).get(), CreateJavaInterface (new DialogListener (callback, 0), "android/content/DialogInterface$OnClickListener").get())); LocalRef dialog (env->CallObjectMethod (builder.get(), AndroidAlertDialogBuilder.create)); LocalRef window (env->CallObjectMethod (dialog.get(), AndroidDialog.getWindow)); if (Desktop::getInstance().getKioskModeComponent() != nullptr) { env->CallVoidMethod (window.get(), AndroidWindow.setFlags, FLAG_NOT_FOCUSABLE, FLAG_NOT_FOCUSABLE); LocalRef decorView (env->CallObjectMethod (window.get(), AndroidWindow.getDecorView)); env->CallVoidMethod (decorView.get(), AndroidView.setSystemUiVisibility, fullScreenFlags); } env->CallVoidMethod (dialog.get(), AndroidDialog.show); if (Desktop::getInstance().getKioskModeComponent() != nullptr) env->CallVoidMethod (window.get(), AndroidWindow.clearFlags, FLAG_NOT_FOCUSABLE); } void JUCE_CALLTYPE NativeMessageBox::showMessageBoxAsync (AlertWindow::AlertIconType /*iconType*/, const String& title, const String& message, Component* /*associatedComponent*/, ModalComponentManager::Callback* callback) { createAndroidDialog (title, message, callback); } bool JUCE_CALLTYPE NativeMessageBox::showOkCancelBox (AlertWindow::AlertIconType /*iconType*/, const String& title, const String& message, Component* /*associatedComponent*/, ModalComponentManager::Callback* callback) { jassert (callback != nullptr); // on android, all alerts must be non-modal!! createAndroidDialog (title, message, callback, "OK", "Cancel"); return false; } int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (AlertWindow::AlertIconType /*iconType*/, const String& title, const String& message, Component* /*associatedComponent*/, ModalComponentManager::Callback* callback) { jassert (callback != nullptr); // on android, all alerts must be non-modal!! createAndroidDialog (title, message, callback, "Yes", "No", "Cancel"); return 0; } int JUCE_CALLTYPE NativeMessageBox::showYesNoBox (AlertWindow::AlertIconType /*iconType*/, const String& title, const String& message, Component* /*associatedComponent*/, ModalComponentManager::Callback* callback) { jassert (callback != nullptr); // on android, all alerts must be non-modal!! createAndroidDialog (title, message, callback, "Yes", "No"); return 0; } //============================================================================== static bool androidScreenSaverEnabled = false; void Desktop::setScreenSaverEnabled (bool shouldEnable) { constexpr auto FLAG_KEEP_SCREEN_ON = 0x80; if (shouldEnable != androidScreenSaverEnabled) { LocalRef activity (getMainActivity()); if (activity != nullptr) { auto* env = getEnv(); LocalRef mainWindow (env->CallObjectMethod (activity.get(), AndroidActivity.getWindow)); env->CallVoidMethod(mainWindow.get(), AndroidWindow.setFlags, shouldEnable ? FLAG_KEEP_SCREEN_ON : 0, FLAG_KEEP_SCREEN_ON); } androidScreenSaverEnabled = shouldEnable; } } bool Desktop::isScreenSaverEnabled() { return androidScreenSaverEnabled; } //============================================================================== void Desktop::setKioskComponent (Component* kioskComp, bool enableOrDisable, bool allowMenusAndBars) { ignoreUnused (allowMenusAndBars); if (AndroidComponentPeer* peer = dynamic_cast (kioskComp->getPeer())) peer->setFullScreen (enableOrDisable); else jassertfalse; // (this should have been checked by the caller) } //============================================================================== static jint getAndroidOrientationFlag (int orientations) noexcept { enum { SCREEN_ORIENTATION_LANDSCAPE = 0, SCREEN_ORIENTATION_PORTRAIT = 1, SCREEN_ORIENTATION_USER = 2, SCREEN_ORIENTATION_REVERSE_LANDSCAPE = 8, SCREEN_ORIENTATION_REVERSE_PORTRAIT = 9, SCREEN_ORIENTATION_USER_LANDSCAPE = 11, SCREEN_ORIENTATION_USER_PORTRAIT = 12, }; switch (orientations) { case Desktop::upright: return (jint) SCREEN_ORIENTATION_PORTRAIT; case Desktop::upsideDown: return (jint) SCREEN_ORIENTATION_REVERSE_PORTRAIT; case Desktop::upright + Desktop::upsideDown: return (jint) SCREEN_ORIENTATION_USER_PORTRAIT; case Desktop::rotatedAntiClockwise: return (jint) SCREEN_ORIENTATION_LANDSCAPE; case Desktop::rotatedClockwise: return (jint) SCREEN_ORIENTATION_REVERSE_LANDSCAPE; case Desktop::rotatedClockwise + Desktop::rotatedAntiClockwise: return (jint) SCREEN_ORIENTATION_USER_LANDSCAPE; default: return (jint) SCREEN_ORIENTATION_USER; } } void Desktop::allowedOrientationsChanged() { LocalRef activity (getMainActivity()); if (activity != nullptr) getEnv()->CallVoidMethod (activity.get(), AndroidActivity.setRequestedOrientation, getAndroidOrientationFlag (allowedOrientations)); } //============================================================================== bool juce_areThereAnyAlwaysOnTopWindows() { return false; } //============================================================================== #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ METHOD (create, "", "()V") \ FIELD (density, "density", "F") \ FIELD (widthPixels, "widthPixels", "I") \ FIELD (heightPixels, "heightPixels", "I") DECLARE_JNI_CLASS (AndroidDisplayMetrics, "android/util/DisplayMetrics") #undef JNI_CLASS_MEMBERS //============================================================================== class LayoutChangeListener : public juce::AndroidInterfaceImplementer { public: virtual void onLayoutChange (LocalRef view, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) = 0; private: jobject invoke (jobject proxy, jobject method, jobjectArray args) override { auto* env = getEnv(); auto methodName = juce::juceString ((jstring) env->CallObjectMethod (method, JavaMethod.getName)); if (methodName == "onLayoutChange") { jassert (env->GetArrayLength (args) == 9); LocalRef view (env->GetObjectArrayElement (args, 0)); int dims[8]; for (int i = 1; i < 9; ++i) { LocalRef integer (env->GetObjectArrayElement (args, i)); dims[i - 1] = env->CallIntMethod (integer.get(), JavaInteger.intValue); } onLayoutChange (std::move (view), dims[0], dims[1], dims[2], dims[3], dims[4], dims[5], dims[6], dims[7]); return nullptr; } // invoke base class return AndroidInterfaceImplementer::invoke (proxy, method, args); } std::unique_ptr callback; }; //============================================================================== class MainActivityWindowLayoutListener : public LayoutChangeListener { public: void onLayoutChange (LocalRef /*view*/, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) override { auto newBounds = Rectangle::leftTopRightBottom (left, top, right, bottom); auto oldBounds = Rectangle::leftTopRightBottom (oldLeft, oldTop, oldRight, oldBottom); if (newBounds != oldBounds) { auto& displays = Desktop::getInstance().getDisplays(); auto& mainDisplay = displays.getMainDisplay(); Rectangle userArea = newBounds / mainDisplay.scale; if (userArea != mainDisplay.userArea) const_cast (displays).refresh(); } } }; //============================================================================== void Displays::findDisplays (float masterScale) { auto* env = getEnv(); LocalRef usableSize (env->NewObject (AndroidPoint, AndroidPoint.create, 0, 0)); LocalRef windowServiceString (javaString ("window")); LocalRef displayMetrics (env->NewObject (AndroidDisplayMetrics, AndroidDisplayMetrics.create)); LocalRef windowManager (env->CallObjectMethod (getAppContext().get(), AndroidContext.getSystemService, windowServiceString.get())); LocalRef display (env->CallObjectMethod (windowManager, AndroidWindowManager.getDefaultDisplay)); jmethodID getRealMetricsMethod = env->GetMethodID (AndroidDisplay, "getRealMetrics", "(Landroid/util/DisplayMetrics;)V"); if (getRealMetricsMethod != nullptr) env->CallVoidMethod (display.get(), getRealMetricsMethod, displayMetrics.get()); else env->CallVoidMethod (display.get(), AndroidDisplay.getMetrics, displayMetrics.get()); env->CallVoidMethod (display.get(), AndroidDisplay.getSize, usableSize.get()); Display d; d.isMain = true; d.scale = env->GetFloatField (displayMetrics.get(), AndroidDisplayMetrics.density); d.dpi = (d.scale * 160.f); d.scale *= masterScale; d.totalArea = Rectangle (env->GetIntField (displayMetrics.get(), AndroidDisplayMetrics.widthPixels), env->GetIntField (displayMetrics.get(), AndroidDisplayMetrics.heightPixels)) / d.scale; d.userArea = Rectangle (env->GetIntField (usableSize.get(), AndroidPoint.x), env->GetIntField (usableSize.get(), AndroidPoint.y)) / d.scale; // unfortunately usableSize still contains the nav bar // the best workaround is to try to get the size of the top-level view of // the main activity LocalRef activity (getMainActivity()); if (activity != nullptr) { LocalRef mainWindow (env->CallObjectMethod (activity.get(), AndroidActivity.getWindow)); LocalRef decorView (env->CallObjectMethod (mainWindow.get(), AndroidWindow.getDecorView)); LocalRef contentView (env->CallObjectMethod (decorView.get(), AndroidView.findViewById, 0x01020002 /* android.R.id.content */)); if (contentView != nullptr) { Rectangle activityArea (env->CallIntMethod (contentView.get(), AndroidView.getLeft), env->CallIntMethod (contentView.get(), AndroidView.getTop), env->CallIntMethod (contentView.get(), AndroidView.getWidth), env->CallIntMethod (contentView.get(), AndroidView.getHeight)); if (! activityArea.isEmpty()) d.userArea = activityArea / d.scale; static bool hasAddedMainActivityListener = false; if (! hasAddedMainActivityListener) { hasAddedMainActivityListener = true; env->CallVoidMethod (contentView.get(), AndroidView.addOnLayoutChangeListener, CreateJavaInterface (new MainActivityWindowLayoutListener, "android/view/View$OnLayoutChangeListener").get()); } } } else { // the main activity may have not started yet so add an activity listener if (AndroidComponentPeer::activityCallbackListener == nullptr) { LocalRef appContext (getAppContext()); if (appContext.get() != nullptr) { AndroidComponentPeer::activityCallbackListener = GlobalRef (CreateJavaInterface ( new AndroidComponentPeer::StartupActivityCallbackListener, "android/app/Application$ActivityLifecycleCallbacks")); env->CallVoidMethod (appContext.get(), AndroidApplication.registerActivityLifecycleCallbacks, AndroidComponentPeer::activityCallbackListener.get()); } } } displays.add (d); } //============================================================================== Image juce_createIconForFile (const File& /*file*/) { return Image(); } //============================================================================== void* CustomMouseCursorInfo::create() const { return nullptr; } void* MouseCursor::createStandardMouseCursor (MouseCursor::StandardCursorType) { return nullptr; } void MouseCursor::deleteMouseCursor (void* /*cursorHandle*/, bool /*isStandard*/) {} //============================================================================== void MouseCursor::showInWindow (ComponentPeer*) const {} //============================================================================== bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& /*files*/, bool /*canMove*/, Component* /*srcComp*/, std::function /*callback*/) { jassertfalse; // no such thing on Android! return false; } bool DragAndDropContainer::performExternalDragDropOfText (const String& /*text*/, Component* /*srcComp*/, std::function /*callback*/) { jassertfalse; // no such thing on Android! return false; } //============================================================================== void LookAndFeel::playAlertSound() { } //============================================================================== #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ METHOD (getText, "getText", "()Ljava/lang/CharSequence;") \ METHOD (setText, "setText", "(Ljava/lang/CharSequence;)V") DECLARE_JNI_CLASS (AndroidClipboardManager, "android/content/ClipboardManager") #undef JNI_CLASS_MEMBERS //============================================================================== void SystemClipboard::copyTextToClipboard (const String& text) { auto* env = getEnv(); LocalRef clipboardManager (env->CallObjectMethod (getAppContext().get(), AndroidContext.getSystemService, javaString ("clipboard").get())); env->CallVoidMethod (clipboardManager.get(), AndroidClipboardManager.setText, javaString(text).get()); } String SystemClipboard::getTextFromClipboard() { auto* env = getEnv(); LocalRef clipboardManager (env->CallObjectMethod (getAppContext().get(), AndroidContext.getSystemService, javaString ("clipboard").get())); LocalRef charSequence (env->CallObjectMethod (clipboardManager.get(), AndroidClipboardManager.getText)); if (charSequence == nullptr) return {}; return juceString(LocalRef ((jstring) env->CallObjectMethod(charSequence.get(), JavaCharSequence.toString))); } //============================================================================== const int extendedKeyModifier = 0x10000; const int KeyPress::spaceKey = ' '; const int KeyPress::returnKey = 66; const int KeyPress::escapeKey = 4; const int KeyPress::backspaceKey = 67; const int KeyPress::leftKey = extendedKeyModifier + 1; const int KeyPress::rightKey = extendedKeyModifier + 2; const int KeyPress::upKey = extendedKeyModifier + 3; const int KeyPress::downKey = extendedKeyModifier + 4; const int KeyPress::pageUpKey = extendedKeyModifier + 5; const int KeyPress::pageDownKey = extendedKeyModifier + 6; const int KeyPress::endKey = extendedKeyModifier + 7; const int KeyPress::homeKey = extendedKeyModifier + 8; const int KeyPress::deleteKey = extendedKeyModifier + 9; const int KeyPress::insertKey = -1; const int KeyPress::tabKey = 61; const int KeyPress::F1Key = extendedKeyModifier + 10; const int KeyPress::F2Key = extendedKeyModifier + 11; const int KeyPress::F3Key = extendedKeyModifier + 12; const int KeyPress::F4Key = extendedKeyModifier + 13; const int KeyPress::F5Key = extendedKeyModifier + 14; const int KeyPress::F6Key = extendedKeyModifier + 16; const int KeyPress::F7Key = extendedKeyModifier + 17; const int KeyPress::F8Key = extendedKeyModifier + 18; const int KeyPress::F9Key = extendedKeyModifier + 19; const int KeyPress::F10Key = extendedKeyModifier + 20; const int KeyPress::F11Key = extendedKeyModifier + 21; const int KeyPress::F12Key = extendedKeyModifier + 22; const int KeyPress::F13Key = extendedKeyModifier + 23; const int KeyPress::F14Key = extendedKeyModifier + 24; const int KeyPress::F15Key = extendedKeyModifier + 25; const int KeyPress::F16Key = extendedKeyModifier + 26; const int KeyPress::F17Key = extendedKeyModifier + 50; const int KeyPress::F18Key = extendedKeyModifier + 51; const int KeyPress::F19Key = extendedKeyModifier + 52; const int KeyPress::F20Key = extendedKeyModifier + 53; const int KeyPress::F21Key = extendedKeyModifier + 54; const int KeyPress::F22Key = extendedKeyModifier + 55; const int KeyPress::F23Key = extendedKeyModifier + 56; const int KeyPress::F24Key = extendedKeyModifier + 57; const int KeyPress::F25Key = extendedKeyModifier + 58; const int KeyPress::F26Key = extendedKeyModifier + 59; const int KeyPress::F27Key = extendedKeyModifier + 60; const int KeyPress::F28Key = extendedKeyModifier + 61; const int KeyPress::F29Key = extendedKeyModifier + 62; const int KeyPress::F30Key = extendedKeyModifier + 63; const int KeyPress::F31Key = extendedKeyModifier + 64; const int KeyPress::F32Key = extendedKeyModifier + 65; const int KeyPress::F33Key = extendedKeyModifier + 66; const int KeyPress::F34Key = extendedKeyModifier + 67; const int KeyPress::F35Key = extendedKeyModifier + 68; const int KeyPress::numberPad0 = extendedKeyModifier + 27; const int KeyPress::numberPad1 = extendedKeyModifier + 28; const int KeyPress::numberPad2 = extendedKeyModifier + 29; const int KeyPress::numberPad3 = extendedKeyModifier + 30; const int KeyPress::numberPad4 = extendedKeyModifier + 31; const int KeyPress::numberPad5 = extendedKeyModifier + 32; const int KeyPress::numberPad6 = extendedKeyModifier + 33; const int KeyPress::numberPad7 = extendedKeyModifier + 34; const int KeyPress::numberPad8 = extendedKeyModifier + 35; const int KeyPress::numberPad9 = extendedKeyModifier + 36; const int KeyPress::numberPadAdd = extendedKeyModifier + 37; const int KeyPress::numberPadSubtract = extendedKeyModifier + 38; const int KeyPress::numberPadMultiply = extendedKeyModifier + 39; const int KeyPress::numberPadDivide = extendedKeyModifier + 40; const int KeyPress::numberPadSeparator = extendedKeyModifier + 41; const int KeyPress::numberPadDecimalPoint = extendedKeyModifier + 42; const int KeyPress::numberPadEquals = extendedKeyModifier + 43; const int KeyPress::numberPadDelete = extendedKeyModifier + 44; const int KeyPress::playKey = extendedKeyModifier + 45; const int KeyPress::stopKey = extendedKeyModifier + 46; const int KeyPress::fastForwardKey = extendedKeyModifier + 47; const int KeyPress::rewindKey = extendedKeyModifier + 48; } // namespace juce