diff --git a/res/raw-sw600dp/lottie_button_nav_menu.json b/res/raw-sw600dp/lottie_button_nav_menu.json new file mode 100644 index 00000000000..16b5ef31ca0 --- /dev/null +++ b/res/raw-sw600dp/lottie_button_nav_menu.json @@ -0,0 +1 @@ +{"v":"5.8.1","fr":60,"ip":0,"op":300,"w":412,"h":300,"nm":"Home Button","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":125,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":132,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":220,"s":[100]},{"t":227,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":115,"s":[206,192.75,0],"to":[0,-2.583,0],"ti":[0,2.583,0]},{"i":{"x":0.3,"y":0.3},"o":{"x":0.7,"y":0.7},"t":155,"s":[206,177.25,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.3,"y":1},"o":{"x":0.8,"y":0},"t":210,"s":[206,177.25,0],"to":[0,3.417,0],"ti":[0,-3.417,0]},{"t":235,"s":[206,197.75,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[40,40,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[4.636,0],[0,4.636],[0,0],[-5.694,-0.823],[0,0],[0,0],[0,0],[0,5.93]],"o":[[0,4.636],[-4.636,0],[0,0],[0,5.93],[0,0],[0,0],[0,0],[5.694,-0.823],[0,0]],"v":[[8.399,61.968],[0,70.367],[-8.399,61.968],[-11.758,61.968],[-1.68,73.592],[-1.68,78.766],[1.68,78.766],[1.68,73.592],[11.758,61.968]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-2.788,0],[0,2.788],[0,0],[2.788,0],[0,-2.788],[0,0]],"o":[[2.788,0],[0,0],[0,-2.788],[-2.788,0],[0,0],[0,2.788]],"v":[[0,67.007],[5.039,61.968],[5.039,51.89],[0,46.85],[-5.039,51.89],[-5.039,61.968]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.4,0.61568627451,0.964705882353,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":70,"op":1534,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":3,"nm":"Null 1","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[208.25,164,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[113.25,113.25,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":1500,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Shape Layer 3","parent":2,"td":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":110,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":118.334,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":231.666,"s":[100]},{"t":240,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-1.987,43.709,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[88.3,88.3,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":110,"s":[{"i":[[0,-5.523],[0,0],[5.523,0],[0,0],[0,5.523],[0,0],[-5.523,0],[0,0]],"o":[[0,0],[0,5.523],[0,0],[-5.523,0],[0,0],[0,-5.523],[0,0],[5.523,0]],"v":[[161,5.5],[161,27],[151,37],[-151,37],[-161,27],[-161,5.5],[-151,-4.5],[151,-4.5]],"c":true}]},{"i":{"x":0.3,"y":0.3},"o":{"x":0.7,"y":0.7},"t":143,"s":[{"i":[[0,-5.523],[0,0],[5.523,0],[0,0],[0,5.523],[0,0],[-5.523,0],[0,0]],"o":[[0,0],[0,5.523],[0,0],[-5.523,0],[0,0],[0,-5.523],[0,0],[5.523,0]],"v":[[161,-19.5],[161,27],[151,37],[-151,37],[-161,27],[-161,-19.5],[-151,-29.5],[151,-29.5]],"c":true}]},{"i":{"x":0.3,"y":1},"o":{"x":0.8,"y":0},"t":215,"s":[{"i":[[0,-5.523],[0,0],[5.523,0],[0,0],[0,5.523],[0,0],[-5.523,0],[0,0]],"o":[[0,0],[0,5.523],[0,0],[-5.523,0],[0,0],[0,-5.523],[0,0],[5.523,0]],"v":[[161,-19.5],[161,27],[151,37],[-151,37],[-161,27],[-161,-19.5],[-151,-29.5],[151,-29.5]],"c":true}]},{"t":240,"s":[{"i":[[0,-5.523],[0,0],[5.523,0],[0,0],[0,5.523],[0,0],[0,0.25],[0,0]],"o":[[0,0],[0,5.523],[0,0],[-5.523,0],[0,0],[0,-5.523],[0,0],[-1.125,0]],"v":[[161,5.5],[161,27],[151,37],[-151,37],[-161,27],[-161,5.5],[-161,-4.5],[161,-4.5]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":1500,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"NGA Line Outlines","parent":2,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1.5,49.474,0],"ix":2,"l":2},"a":{"a":0,"k":[45.896,0.896,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":115,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[185.882,0.94],[208.382,0.94]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":139,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[42.387,0.911],[63.59,0.911]],"c":false}]},{"i":{"x":0.3,"y":1},"o":{"x":0.7,"y":0},"t":155,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[42.385,0.887],[70.714,0.923]],"c":false}]},{"i":{"x":0.3,"y":1},"o":{"x":0.8,"y":0},"t":210,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[42.416,0.911],[70.714,0.923]],"c":false}]},{"t":235,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[185.992,0.94],[208.492,0.94]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.258823543787,0.521568655968,0.956862747669,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.793,"ix":5},"lc":1,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Yellow","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":115,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[208.382,0.94],[230.882,0.94]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":139,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[63.59,0.911],[87.443,0.911]],"c":false}]},{"i":{"x":0.3,"y":1},"o":{"x":0.7,"y":0},"t":155,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[70.714,0.923],[98.844,0.923]],"c":false}]},{"i":{"x":0.3,"y":1},"o":{"x":0.8,"y":0},"t":210,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[70.714,0.923],[98.844,0.923]],"c":false}]},{"t":235,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[208.492,0.94],[230.992,0.94]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.258823543787,0.521568655968,0.956862747669,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.793,"ix":5},"lc":1,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Green","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":115,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-123.053,0.94],[-100.553,0.94]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":139,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[21.184,0.911],[42.387,0.911]],"c":false}]},{"i":{"x":0.3,"y":1},"o":{"x":0.7,"y":0},"t":155,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[14.13,0.887],[42.385,0.887]],"c":false}]},{"i":{"x":0.3,"y":1},"o":{"x":0.8,"y":0},"t":210,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[14.13,0.887],[42.416,0.911]],"c":false}]},{"t":235,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-123.273,0.94],[-100.773,0.94]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.258823543787,0.521568655968,0.956862747669,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.793,"ix":5},"lc":1,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Red","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":115,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-145.553,0.94],[-123.053,0.94]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":139,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-1.972,0.911],[21.184,0.911]],"c":false}]},{"i":{"x":0.3,"y":1},"o":{"x":0.7,"y":0},"t":155,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-14.06,0.911],[14.13,0.887]],"c":false}]},{"i":{"x":0.3,"y":1},"o":{"x":0.8,"y":0},"t":210,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-14.06,0.911],[14.13,0.887]],"c":false}]},{"t":235,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-145.773,0.94],[-123.273,0.94]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.258999992819,0.522000002394,0.957000014361,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.793,"ix":5},"lc":1,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Blue","np":2,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false}],"ip":115,"op":236,"st":35,"bm":0},{"ddd":0,"ind":8,"ty":3,"nm":"Null 8","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[319.75,114.25,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":1500,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Buttons","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[319.843,229.28,0],"ix":2,"l":2},"a":{"a":0,"k":[319.843,229.28,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[4.355,-4.355],[-4.355,-4.355],[-4.355,4.355],[4.355,4.355]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.737254917622,0.745098054409,0.752941191196,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[345.684,229.275],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 8","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.402,0],[0,2.402],[2.403,0],[0,-2.403]],"o":[[2.403,0],[0,-2.403],[-2.402,0],[0,2.402]],"v":[[0,4.35],[4.35,0],[0,-4.35],[-4.35,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.737254917622,0.745098054409,0.752941191196,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":80,"s":[100,100]},{"i":{"x":[0.3,0.3],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":90,"s":[0,0]},{"i":{"x":[0.3,0.3],"y":[1,1]},"o":{"x":[0.8,0.8],"y":[0,0]},"t":107,"s":[0,0]},{"t":116,"s":[100,100]}],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[319.548,229.28],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 7","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-3.77,-0.005],[3.77,-4.355],[3.77,4.355],[-3.77,0.005]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.737254917622,0.745098054409,0.752941191196,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[293.417,229.285],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 6","np":1,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":1500,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Gesture Tap","parent":8,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,114.812,0],"ix":2,"l":2},"a":{"a":0,"k":[273.205,92.869,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-5.226],[-5.226,0],[0,5.226],[5.226,0]],"o":[[0,5.226],[5.226,0],[0,-5.226],[-5.226,0]],"v":[[-9.463,0],[0,9.463],[9.463,0],[0,-9.463]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[273.205,92.869],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.239,0.239],"y":[0.677,0.677]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":40,"s":[0,0]},{"i":{"x":[0.596,0.596],"y":[1,1]},"o":{"x":[0.182,0.182],"y":[0.207,0.207]},"t":55,"s":[80,80]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.793,0.793],"y":[0,0]},"t":75,"s":[120,120]},{"t":85,"s":[0,0]}],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":40,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-8.26],[-8.26,0],[0,8.26],[8.26,0]],"o":[[0,8.26],[8.26,0],[0,-8.26],[-8.26,0]],"v":[[-14.957,0],[0,14.957],[14.957,0],[0,-14.957]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[273.205,92.869],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.304,0.304],"y":[0.802,0.802]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":30,"s":[0,0]},{"i":{"x":[0.709,0.709],"y":[0.997,0.997]},"o":{"x":[0.196,0.196],"y":[0.446,0.446]},"t":45,"s":[80,80]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.609,0.609],"y":[0,0]},"t":75,"s":[100,100]},{"t":85,"s":[0,0]}],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":40,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":1500,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Blue_Dot","parent":8,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":80,"s":[0.025]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":90,"s":[-5.218]},{"i":{"x":[0.999],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":102,"s":[-15.702]},{"t":111,"s":[0.025]}],"ix":3},"y":{"a":0,"k":114.925,"ix":4}},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[34.95,34.95,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.4,0.4],"y":[0,0]},"t":80,"s":[10,10]},{"t":93,"s":[8,8]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.101960785687,0.450980395079,0.909803926945,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":80,"op":118,"st":10,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Yellow_Dot","parent":8,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":90,"s":[0.025]},{"i":{"x":[0.999],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":102,"s":[5.267]},{"t":110,"s":[0.025]}],"ix":3},"y":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":80,"s":[114.925]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":90,"s":[120.168]},{"t":98,"s":[114.925]}],"ix":4}},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[34.95,34.95,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.4,0.4],"y":[0,0]},"t":80,"s":[10,10]},{"t":93,"s":[8,8]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.976470589638,0.670588254929,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":80,"op":112,"st":10,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Red_Dot","parent":8,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":90,"s":[0.025]},{"i":{"x":[0.999],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":102,"s":[-5.218]},{"t":110,"s":[0.025]}],"ix":3},"y":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":80,"s":[114.925]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":90,"s":[109.683]},{"t":98,"s":[114.925]}],"ix":4}},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[34.95,34.95,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.4,0.4],"y":[0,0]},"t":80,"s":[10,10]},{"t":93,"s":[8,8]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.850980401039,0.188235297799,0.145098045468,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":80,"op":111,"st":10,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Green_Dot","parent":8,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":80,"s":[0.025]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":90,"s":[5.267]},{"i":{"x":[0.999],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":102,"s":[15.752]},{"t":111,"s":[0.025]}],"ix":3},"y":{"a":0,"k":114.925,"ix":4}},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[34.95,34.95,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.4,0.4],"y":[0,0]},"t":80,"s":[10,10]},{"t":93,"s":[8,8]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.117647059262,0.556862771511,0.243137255311,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":80,"op":112,"st":10,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":".black","cl":"black","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":110,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":118.334,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":231.666,"s":[100]},{"t":240,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,213.5,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":110,"s":[{"i":[[0,-5.523],[0,0],[5.523,0],[0,0],[0,5.523],[0,0],[0,0.25],[0,0]],"o":[[0,0],[0,5.523],[0,0],[-5.523,0],[0,0],[0,-5.523],[0,0],[-1.125,0]],"v":[[161,5.5],[161,27],[151,37],[-151,37],[-161,27],[-161,5.5],[-161,-4.5],[161,-4.5]],"c":true}]},{"i":{"x":0.3,"y":0.3},"o":{"x":0.7,"y":0.7},"t":143,"s":[{"i":[[0,-5.523],[0,0],[5.523,0],[0,0],[0,5.523],[0,0],[-5.523,0],[0,0]],"o":[[0,0],[0,5.523],[0,0],[-5.523,0],[0,0],[0,-5.523],[0,0],[5.523,0]],"v":[[161,-19.5],[161,27],[151,37],[-151,37],[-161,27],[-161,-19.5],[-151,-29.5],[151,-29.5]],"c":true}]},{"i":{"x":0.3,"y":1},"o":{"x":0.8,"y":0},"t":215,"s":[{"i":[[0,-5.523],[0,0],[5.523,0],[0,0],[0,5.523],[0,0],[-5.523,0],[0,0]],"o":[[0,0],[0,5.523],[0,0],[-5.523,0],[0,0],[0,-5.523],[0,0],[5.523,0]],"v":[[161,-19.5],[161,27],[151,37],[-151,37],[-161,27],[-161,-19.5],[-151,-29.5],[151,-29.5]],"c":true}]},{"t":240,"s":[{"i":[[0,-5.523],[0,0],[5.523,0],[0,0],[0,5.523],[0,0],[0,0.25],[0,0]],"o":[[0,0],[0,5.523],[0,0],[-5.523,0],[0,0],[0,-5.523],[0,0],[-1.125,0]],"v":[[161,5.5],[161,27],[151,37],[-151,37],[-161,27],[-161,5.5],[-161,-4.5],[161,-4.5]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":1500,"st":0,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":".grey600","cl":"grey600","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206.01,149.85,0],"ix":2,"l":2},"a":{"a":0,"k":[206.01,149.85,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[1.28,0],[0,0],[0,-1.28]],"o":[[0,-1.28],[0,0],[-1.28,0],[0,0]],"v":[[6.935,1.155],[4.625,-1.155],[-4.625,-1.155],[-6.935,1.155]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960784314,0.525490196078,0.545098039216,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[337.493,48.485],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 4","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[1.27,0],[0,0],[0,-1.28],[0,0]],"o":[[0,-1.28],[0,0],[-1.28,0],[0,0],[0,0]],"v":[[13.86,1.155],[11.55,-1.155],[-11.56,-1.155],[-13.87,1.155],[13.87,1.155]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960784314,0.525490196078,0.545098039216,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[305.976,48.485],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 3","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[4.15,0],[0,0],[0,4.15],[0,0],[-4.15,0],[0,0],[0,-4.15],[0,0]],"o":[[0,4.15],[0,0],[-4.15,0],[0,0],[0,-4.15],[0,0],[4.15,0],[0,0],[0,0]],"v":[[159.899,92.5],[151.998,100.02],[-151.979,100.02],[-159.879,92.5],[-159.879,-90.09],[-151.979,-97.99],[151.998,-97.99],[159.899,-90.09],[159.899,92.49]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[5.671,0],[0,0],[0,-5.67],[0,0],[-5.67,0],[0,0],[0,5.67],[0,0]],"o":[[0,0],[0,-5.67],[0,0],[-5.67,0],[0,0],[0,5.67],[0,0],[5.671,0],[0,0],[0,0]],"v":[[162.259,-7.17],[162.259,-90.09],[151.998,-100.35],[-151.979,-100.35],[-162.239,-90.09],[-162.239,92.11],[-151.979,102.37],[151.998,102.37],[162.259,92.11],[162.259,-7.18]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960784314,0.525490196078,0.545098039216,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 2","np":1,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":1500,"st":0,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":".grey700","cl":"grey700","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,130.5,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,-5.523],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[5.523,0]],"o":[[-5.523,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,-5.523],[0,0]],"v":[[-151,-78.5],[-161,-68.5],[-161,-52.5],[-161,68.5],[-161,78.5],[-151,78.5],[151,78.5],[161,78.5],[161,68.5],[161,-52.5],[161,-68.5],[151,-78.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.372549027205,0.388235300779,0.407843142748,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":1500,"st":0,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":".black","cl":"black","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[15.291,0],[0,0],[0,15.652],[0,0],[-15.291,0],[0,0],[0,-15.652],[0,0]],"o":[[0,0],[-15.291,0],[0,0],[0,-15.652],[0,0],[15.185,0],[0,0],[0,15.544]],"v":[[178.179,150],[-178.179,150],[-206,121.522],[-206,-121.522],[-178.179,-150],[178.286,-150],[206,-121.522],[206,121.63]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":1500,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/res/xml/button_navigation_settings.xml b/res/xml/button_navigation_settings.xml index 1153c6767ad..2459b602d1c 100644 --- a/res/xml/button_navigation_settings.xml +++ b/res/xml/button_navigation_settings.xml @@ -26,6 +26,7 @@ diff --git a/src/com/android/settings/biometrics/MultiBiometricEnrollHelper.java b/src/com/android/settings/biometrics/MultiBiometricEnrollHelper.java index a994b9564d9..d85f446d1a3 100644 --- a/src/com/android/settings/biometrics/MultiBiometricEnrollHelper.java +++ b/src/com/android/settings/biometrics/MultiBiometricEnrollHelper.java @@ -24,8 +24,11 @@ import android.hardware.fingerprint.FingerprintManager; import androidx.annotation.NonNull; import androidx.fragment.app.FragmentActivity; +import com.android.internal.annotations.VisibleForTesting; import com.android.settings.password.ChooseLockSettingsHelper; +import java.util.function.Function; + /** * Helper for {@link BiometricEnrollActivity} when multiple sensors exist on a device. */ @@ -45,14 +48,39 @@ public class MultiBiometricEnrollHelper { private final int mUserId; private final boolean mRequestEnrollFace; private final boolean mRequestEnrollFingerprint; + private final FingerprintManager mFingerprintManager; + private final FaceManager mFaceManager; + private final Intent mFingerprintEnrollIntroductionIntent; + private final Intent mFaceEnrollIntroductionIntent; + private Function mGatekeeperHatSupplier; + @VisibleForTesting MultiBiometricEnrollHelper(@NonNull FragmentActivity activity, int userId, - boolean enrollFace, boolean enrollFingerprint, long gkPwHandle) { + boolean enrollFace, boolean enrollFingerprint, long gkPwHandle, + FingerprintManager fingerprintManager, + FaceManager faceManager, Intent fingerprintEnrollIntroductionIntent, + Intent faceEnrollIntroductionIntent, Function gatekeeperHatSupplier) { mActivity = activity; mUserId = userId; mGkPwHandle = gkPwHandle; mRequestEnrollFace = enrollFace; mRequestEnrollFingerprint = enrollFingerprint; + mFingerprintManager = fingerprintManager; + mFaceManager = faceManager; + mFingerprintEnrollIntroductionIntent = fingerprintEnrollIntroductionIntent; + mFaceEnrollIntroductionIntent = faceEnrollIntroductionIntent; + mGatekeeperHatSupplier = gatekeeperHatSupplier; + } + + MultiBiometricEnrollHelper(@NonNull FragmentActivity activity, int userId, + boolean enrollFace, boolean enrollFingerprint, long gkPwHandle) { + this(activity, userId, enrollFace, enrollFingerprint, gkPwHandle, + activity.getSystemService(FingerprintManager.class), + activity.getSystemService(FaceManager.class), + BiometricUtils.getFingerprintIntroIntent(activity, activity.getIntent()), + BiometricUtils.getFaceIntroIntent(activity, activity.getIntent()), + (challenge) -> BiometricUtils.requestGatekeeperHat(activity, gkPwHandle, + userId, challenge)); } void startNextStep() { @@ -67,45 +95,39 @@ public class MultiBiometricEnrollHelper { } private void launchFaceEnroll() { - final FaceManager faceManager = mActivity.getSystemService(FaceManager.class); - faceManager.generateChallenge(mUserId, (sensorId, userId, challenge) -> { - final byte[] hardwareAuthToken = BiometricUtils.requestGatekeeperHat(mActivity, - mGkPwHandle, mUserId, challenge); - final Intent faceIntent = BiometricUtils.getFaceIntroIntent(mActivity, - mActivity.getIntent()); - faceIntent.putExtra(BiometricEnrollBase.EXTRA_KEY_SENSOR_ID, sensorId); - faceIntent.putExtra(BiometricEnrollBase.EXTRA_KEY_CHALLENGE, challenge); - BiometricUtils.launchEnrollForResult(mActivity, faceIntent, REQUEST_FACE_ENROLL, - hardwareAuthToken, mGkPwHandle, mUserId); + mFaceManager.generateChallenge(mUserId, (sensorId, userId, challenge) -> { + final byte[] hardwareAuthToken = mGatekeeperHatSupplier.apply(challenge); + mFaceEnrollIntroductionIntent.putExtra( + BiometricEnrollBase.EXTRA_KEY_SENSOR_ID, sensorId); + mFaceEnrollIntroductionIntent.putExtra( + BiometricEnrollBase.EXTRA_KEY_CHALLENGE, challenge); + BiometricUtils.launchEnrollForResult(mActivity, mFaceEnrollIntroductionIntent, + REQUEST_FACE_ENROLL, hardwareAuthToken, mGkPwHandle, mUserId); }); } private void launchFingerprintEnroll() { - final FingerprintManager fingerprintManager = mActivity - .getSystemService(FingerprintManager.class); - fingerprintManager.generateChallenge(mUserId, ((sensorId, userId, challenge) -> { - final byte[] hardwareAuthToken = BiometricUtils.requestGatekeeperHat(mActivity, - mGkPwHandle, mUserId, challenge); - final Intent intent = BiometricUtils.getFingerprintIntroIntent(mActivity, - mActivity.getIntent()); - intent.putExtra(BiometricEnrollBase.EXTRA_KEY_SENSOR_ID, sensorId); - intent.putExtra(BiometricEnrollBase.EXTRA_KEY_CHALLENGE, challenge); + mFingerprintManager.generateChallenge(mUserId, ((sensorId, userId, challenge) -> { + final byte[] hardwareAuthToken = mGatekeeperHatSupplier.apply(challenge); + mFingerprintEnrollIntroductionIntent.putExtra( + BiometricEnrollBase.EXTRA_KEY_SENSOR_ID, sensorId); + mFingerprintEnrollIntroductionIntent.putExtra( + BiometricEnrollBase.EXTRA_KEY_CHALLENGE, challenge); if (mRequestEnrollFace) { // Give FingerprintEnroll a pendingIntent pointing to face enrollment, so that it // can be started when user skips or finishes fingerprint enrollment. // FLAG_UPDATE_CURRENT ensures it is launched with the most recent values. - final Intent faceIntent = BiometricUtils.getFaceIntroIntent(mActivity, - mActivity.getIntent()); - faceIntent.putExtra(Intent.EXTRA_USER_ID, mUserId); - faceIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE, - mGkPwHandle); + mFaceEnrollIntroductionIntent.putExtra(Intent.EXTRA_USER_ID, mUserId); + mFaceEnrollIntroductionIntent.putExtra( + ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE, mGkPwHandle); final PendingIntent faceAfterFp = PendingIntent.getActivity(mActivity, - 0 /* requestCode */, faceIntent, + 0 /* requestCode */, mFaceEnrollIntroductionIntent, PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT); - intent.putExtra(EXTRA_ENROLL_AFTER_FINGERPRINT, faceAfterFp); + mFingerprintEnrollIntroductionIntent.putExtra(EXTRA_ENROLL_AFTER_FINGERPRINT, + faceAfterFp); } - BiometricUtils.launchEnrollForResult(mActivity, intent, REQUEST_FINGERPRINT_ENROLL, - hardwareAuthToken, mGkPwHandle, mUserId); + BiometricUtils.launchEnrollForResult(mActivity, mFingerprintEnrollIntroductionIntent, + REQUEST_FINGERPRINT_ENROLL, hardwareAuthToken, mGkPwHandle, mUserId); })); } } diff --git a/src/com/android/settings/localepicker/AppLocalePickerActivity.java b/src/com/android/settings/localepicker/AppLocalePickerActivity.java index b7fef30a58e..691344da60f 100644 --- a/src/com/android/settings/localepicker/AppLocalePickerActivity.java +++ b/src/com/android/settings/localepicker/AppLocalePickerActivity.java @@ -19,6 +19,7 @@ package com.android.settings.localepicker; import android.app.FragmentTransaction; import android.app.LocaleManager; import android.content.Context; +import android.content.pm.PackageManager; import android.net.Uri; import android.os.Bundle; import android.os.LocaleList; @@ -34,6 +35,7 @@ import com.android.internal.app.LocalePickerWithRegion; import com.android.internal.app.LocaleStore; import com.android.settings.R; import com.android.settings.applications.AppInfoBase; +import com.android.settings.applications.AppLocaleUtil; import com.android.settings.applications.appinfo.AppLocaleDetails; import com.android.settings.core.SettingsBaseActivity; @@ -64,12 +66,17 @@ public class AppLocalePickerActivity extends SettingsBaseActivity } mContextAsUser = this; if (getIntent().hasExtra(AppInfoBase.ARG_PACKAGE_UID)) { - int userId = getIntent().getIntExtra(AppInfoBase.ARG_PACKAGE_UID, -1); - if (userId != -1) { - UserHandle userHandle = UserHandle.getUserHandleForUid(userId); + int uid = getIntent().getIntExtra(AppInfoBase.ARG_PACKAGE_UID, -1); + if (uid != -1) { + UserHandle userHandle = UserHandle.getUserHandleForUid(uid); mContextAsUser = createContextAsUser(userHandle, 0); } } + if (!canDisplayLocaleUi() || mContextAsUser.getUserId() != UserHandle.myUserId()) { + Log.w(TAG, "Not allow to display Locale Settings UI."); + finish(); + return; + } setTitle(R.string.app_locale_picker_title); getActionBar().setDisplayHomeAsUpEnabled(true); @@ -160,4 +167,10 @@ public class AppLocalePickerActivity extends SettingsBaseActivity .replace(R.id.content_frame, mLocalePickerWithRegion) .commit(); } + + private boolean canDisplayLocaleUi() { + return AppLocaleUtil.canDisplayLocaleUi(mContextAsUser, mPackageName, + mContextAsUser.getPackageManager().queryIntentActivities( + AppLocaleUtil.LAUNCHER_ENTRY_INTENT, PackageManager.GET_META_DATA)); + } } diff --git a/tests/robotests/src/com/android/settings/biometrics/MultiBiometricEnrollHelperTest.java b/tests/robotests/src/com/android/settings/biometrics/MultiBiometricEnrollHelperTest.java new file mode 100644 index 00000000000..03b3b48461d --- /dev/null +++ b/tests/robotests/src/com/android/settings/biometrics/MultiBiometricEnrollHelperTest.java @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.biometrics; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.verify; +import static org.robolectric.Shadows.shadowOf; + +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.hardware.face.FaceManager; +import android.hardware.fingerprint.FingerprintManager; +import android.os.RemoteException; + +import androidx.fragment.app.FragmentActivity; + +import com.android.settings.biometrics.face.FaceEnrollIntroduction; +import com.android.settings.biometrics.fingerprint.FingerprintEnrollIntroduction; +import com.android.settings.password.ChooseLockSettingsHelper; +import com.android.settings.testutils.shadow.ShadowLockPatternUtils; +import com.android.settings.testutils.shadow.ShadowRestrictedLockUtilsInternal; +import com.android.settings.testutils.shadow.ShadowSensorPrivacyManager; +import com.android.settings.testutils.shadow.ShadowUserManager; +import com.android.settings.testutils.shadow.ShadowUtils; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.android.controller.ActivityController; +import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowPackageManager; + +@RunWith(RobolectricTestRunner.class) +@Config(shadows = { + ShadowUtils.class, + ShadowUserManager.class, + ShadowRestrictedLockUtilsInternal.class, + ShadowSensorPrivacyManager.class, + ShadowLockPatternUtils.class +}) +public class MultiBiometricEnrollHelperTest { + @Rule + public final MockitoRule mockito = MockitoJUnit.rule(); + + @Mock + private FragmentActivity mActivity; + @Mock + private FingerprintManager mFingerprintManager; + @Mock + private FaceManager mFaceManager; + + private Context mContext; + + @Captor + private ArgumentCaptor mFingerprintCaptor; + + private final int mUserId = 10; + private final long mChallenge = 0L; + private final int mSensorId = 0; + private final long mGkPwHandle = 0L; + + private MultiBiometricEnrollHelper mMultiBiometricEnrollHelper; + private Intent mFingerprintIntent; + private Intent mFaceIntent; + + @Before + public void setUp() throws RemoteException { + mContext = RuntimeEnvironment.application.getApplicationContext(); + mFingerprintIntent = new Intent(mContext, FingerprintEnrollIntroduction.class); + mFaceIntent = new Intent(mContext, FaceEnrollIntroduction.class); + mMultiBiometricEnrollHelper = new MultiBiometricEnrollHelper( + mActivity, mUserId, true /* enrollFace */, true /* enrollFingerprint */, + mGkPwHandle, mFingerprintManager, mFaceManager, mFingerprintIntent, mFaceIntent, + (challenge) -> null); + } + + @Test + public void launchFaceAndFingerprintEnroll_testFingerprint() { + mMultiBiometricEnrollHelper.startNextStep(); + + verify(mFingerprintManager).generateChallenge(anyInt(), mFingerprintCaptor.capture()); + + FingerprintManager.GenerateChallengeCallback generateChallengeCallback = + mFingerprintCaptor.getValue(); + generateChallengeCallback.onChallengeGenerated(mSensorId, mUserId, mChallenge); + + assertThat(mFingerprintIntent.hasExtra( + MultiBiometricEnrollHelper.EXTRA_ENROLL_AFTER_FINGERPRINT)).isTrue(); + assertThat(mFingerprintIntent.getExtra(BiometricEnrollBase.EXTRA_KEY_SENSOR_ID, + -1 /* defaultValue */)).isEqualTo(mSensorId); + assertThat(mFingerprintIntent.getExtra(BiometricEnrollBase.EXTRA_KEY_CHALLENGE, + -1 /* defaultValue */)).isEqualTo(mChallenge); + assertThat(mFingerprintIntent.getExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE, + -1 /* defaultValue */)).isEqualTo(mGkPwHandle); + } + + @Test + public void launchFaceAndFingerprintEnroll_testFace() { + mMultiBiometricEnrollHelper.startNextStep(); + + verify(mFingerprintManager).generateChallenge(anyInt(), mFingerprintCaptor.capture()); + + FingerprintManager.GenerateChallengeCallback fingerprintGenerateChallengeCallback = + mFingerprintCaptor.getValue(); + fingerprintGenerateChallengeCallback.onChallengeGenerated( + mSensorId, mUserId, mChallenge); + + assertThat(mFaceIntent.getExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE, + -1 /* defaultValue */)).isEqualTo(mGkPwHandle); + assertThat(mFaceIntent.getIntExtra(Intent.EXTRA_USER_ID, -1 /* defaultValue */)) + .isEqualTo(mUserId); + + final ShadowPackageManager shadowPackageManager = shadowOf(mContext.getPackageManager()); + shadowPackageManager.setSystemFeature(PackageManager.FEATURE_FACE, true); + ShadowUtils.setFaceManager(mFaceManager); + ActivityController.of(new FaceEnrollIntroduction(), mFaceIntent) + .create(mFaceIntent.getExtras()).get(); + + verify(mFaceManager).generateChallenge(eq(mUserId), any()); + } +} diff --git a/tests/robotests/src/com/android/settings/localepicker/AppLocalePickerActivityTest.java b/tests/robotests/src/com/android/settings/localepicker/AppLocalePickerActivityTest.java index 332a39b3436..77b2abb76dc 100644 --- a/tests/robotests/src/com/android/settings/localepicker/AppLocalePickerActivityTest.java +++ b/tests/robotests/src/com/android/settings/localepicker/AppLocalePickerActivityTest.java @@ -18,25 +18,35 @@ package com.android.settings.localepicker; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.annotation.Nullable; import android.app.Activity; import android.app.ApplicationPackageManager; +import android.app.LocaleConfig; import android.content.Context; import android.content.Intent; +import android.content.pm.ApplicationInfo; import android.content.pm.InstallSourceInfo; +import android.content.pm.PackageInfo; +import android.content.pm.ResolveInfo; +import android.content.res.Resources; import android.net.Uri; +import android.os.LocaleList; import android.os.Process; import android.os.UserHandle; import android.telephony.TelephonyManager; +import androidx.annotation.ArrayRes; + import com.android.internal.app.LocaleStore; import com.android.settings.applications.AppInfoBase; -import java.util.Locale; - +import org.junit.After; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -45,17 +55,26 @@ import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import org.robolectric.Robolectric; import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; import org.robolectric.Shadows; import org.robolectric.android.controller.ActivityController; import org.robolectric.annotation.Config; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; +import org.robolectric.shadows.ShadowPackageManager; import org.robolectric.shadows.ShadowTelephonyManager; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + @RunWith(RobolectricTestRunner.class) @Config( shadows = { AppLocalePickerActivityTest.ShadowApplicationPackageManager.class, + AppLocalePickerActivityTest.ShadowResources.class, + AppLocalePickerActivityTest.ShadowUserHandle.class, + AppLocalePickerActivityTest.ShadowLocaleConfig.class, }) public class AppLocalePickerActivityTest { private static final String TEST_PACKAGE_NAME = "com.android.settings"; @@ -67,21 +86,99 @@ public class AppLocalePickerActivityTest { @Rule public MockitoRule rule = MockitoJUnit.rule(); + private Context mContext; + private ShadowPackageManager mPackageManager; + + @Before + public void setUp() { + mContext = spy(RuntimeEnvironment.application); + mPackageManager = Shadows.shadowOf(mContext.getPackageManager()); + } + + @After + public void tearDown() { + mPackageManager.removePackage(TEST_PACKAGE_NAME); + ShadowResources.setDisAllowPackage(false); + ShadowApplicationPackageManager.setNoLaunchEntry(false); + ShadowUserHandle.setUserId(0); + ShadowLocaleConfig.setStatus(LocaleConfig.STATUS_SUCCESS); + } + @Test public void launchAppLocalePickerActivity_hasPackageName_success() { ActivityController controller = initActivityController(true); - controller.create(); assertThat(controller.get().isFinishing()).isFalse(); } + @Test + public void launchAppLocalePickerActivity_appNoLocaleConfig_failed() { + ShadowLocaleConfig.setStatus(LocaleConfig.STATUS_NOT_SPECIFIED); + + ActivityController controller = + initActivityController(true); + controller.create(); + + assertThat(controller.get().isFinishing()).isTrue(); + } + + @Test + public void launchAppLocalePickerActivity_appSignPlatformKey_failed() { + final ApplicationInfo applicationInfo = new ApplicationInfo(); + applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_SIGNED_WITH_PLATFORM_KEY; + applicationInfo.packageName = TEST_PACKAGE_NAME; + + final PackageInfo packageInfo = new PackageInfo(); + packageInfo.packageName = TEST_PACKAGE_NAME; + packageInfo.applicationInfo = applicationInfo; + mPackageManager.installPackage(packageInfo); + + ActivityController controller = + initActivityController(true); + controller.create(); + + assertThat(controller.get().isFinishing()).isTrue(); + } + + @Test + public void launchAppLocalePickerActivity_appMatchDisallowedPackage_failed() { + ShadowResources.setDisAllowPackage(true); + + ActivityController controller = + initActivityController(true); + controller.create(); + + assertThat(controller.get().isFinishing()).isTrue(); + } + + @Test + public void launchAppLocalePickerActivity_appNoLaunchEntry_failed() { + ShadowApplicationPackageManager.setNoLaunchEntry(true); + + ActivityController controller = + initActivityController(true); + controller.create(); + + assertThat(controller.get().isFinishing()).isTrue(); + } + + @Test + public void launchAppLocalePickerActivity_modifyAppLocalesOfAnotherUser_failed() { + ShadowUserHandle.setUserId(10); + + ActivityController controller = + initActivityController(true); + controller.create(); + + assertThat(controller.get().isFinishing()).isTrue(); + } + @Test public void launchAppLocalePickerActivity_intentWithoutPackageName_failed() { ActivityController controller = initActivityController(false); - controller.create(); assertThat(controller.get().isFinishing()).isTrue(); @@ -125,7 +222,7 @@ public class AppLocalePickerActivityTest { if (hasPackageName) { data.setData(TEST_PACKAGE_URI); } - data.putExtra(AppInfoBase.ARG_PACKAGE_UID, UserHandle.getUserId(Process.myUid())); + data.putExtra(AppInfoBase.ARG_PACKAGE_UID, Process.myUid()); ActivityController activityController = Robolectric.buildActivity(TestAppLocalePickerActivity.class, data); Activity activity = activityController.get(); @@ -149,10 +246,75 @@ public class AppLocalePickerActivityTest { @Implements(ApplicationPackageManager.class) public static class ShadowApplicationPackageManager extends org.robolectric.shadows.ShadowApplicationPackageManager { + private static boolean sNoLaunchEntry = false; @Implementation protected Object getInstallSourceInfo(String packageName) { return new InstallSourceInfo("", null, null, ""); } + + @Implementation + protected List queryIntentActivities(Intent intent, int flags) { + if (sNoLaunchEntry) { + return new ArrayList(); + } else { + return super.queryIntentActivities(intent, flags); + } + } + + private static void setNoLaunchEntry(boolean noLaunchEntry) { + sNoLaunchEntry = noLaunchEntry; + } + } + + @Implements(Resources.class) + public static class ShadowResources extends + org.robolectric.shadows.ShadowResources { + private static boolean sDisAllowPackage = false; + + @Implementation + public String[] getStringArray(@ArrayRes int id) { + if (sDisAllowPackage) { + return new String[]{TEST_PACKAGE_NAME}; + } else { + return new String[0]; + } + } + + private static void setDisAllowPackage(boolean disAllowPackage) { + sDisAllowPackage = disAllowPackage; + } + } + + @Implements(UserHandle.class) + public static class ShadowUserHandle { + private static int sUserId = 0; + private static void setUserId(int userId) { + sUserId = userId; + } + + @Implementation + public static int getUserId(int userId) { + return sUserId; + } + } + + @Implements(LocaleConfig.class) + public static class ShadowLocaleConfig { + private static int sStatus = 0; + + @Implementation + public @Nullable LocaleList getSupportedLocales() { + return LocaleList.forLanguageTags("en-US"); + } + + private static void setStatus(@LocaleConfig.Status int status) { + sStatus = status; + } + + @Implementation + public @LocaleConfig.Status int getStatus() { + return sStatus; + } } }