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;
+ }
}
}