Snap for 6353135 from b7690b92fb to mainline-release

Change-Id: Ia44862e4215204cff847d3284d087cb61ed03f4f
This commit is contained in:
android-build-team Robot
2020-04-01 07:15:32 +00:00
46 changed files with 1256 additions and 710 deletions

View File

@@ -0,0 +1,21 @@
<!--
~ Copyright (C) 2020 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.
-->
<vector android:autoMirrored="true" android:height="24dp"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#4285F4" android:pathData="M12,2C6.49,2 2,6.49 2,12s4.49,10 10,10 10,-4.49 10,-10S17.51,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM14.59,8.59L16,10l-4,4 -4,-4 1.41,-1.41L11,10.17L11,6h2v4.17l1.59,-1.58zM17,17L7,17v-2h10v2z"/>
</vector>

View File

@@ -0,0 +1,54 @@
<!--
Copyright (C) 2020 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="149.0dp"
android:height="106.0dp"
android:viewportWidth="149.0"
android:viewportHeight="106.0">
<path
android:pathData="M124.836,33.3968C124.803,32.0165 123.657,30.924 122.277,30.9566C120.033,31.0096 116.483,30.2834 113.492,28.017C110.609,25.8319 108.065,22.0845 107.846,15.6608C107.799,14.2808 106.642,13.2003 105.262,13.2474C103.882,13.2944 102.802,14.4512 102.849,15.8311C103.117,23.7016 106.344,28.8735 110.472,32.0019C114.493,35.0492 119.194,36.0308 122.395,35.9552C123.776,35.9226 124.868,34.7772 124.836,33.3968Z"
android:fillColor="#DADCE0"/>
<path
android:pathData="M126.906,26.0953C126.873,24.7149 125.728,23.6224 124.347,23.655C123.089,23.6847 121.034,23.2678 119.313,21.9639C117.7,20.7412 116.201,18.6093 116.07,14.7745C116.023,13.3946 114.866,12.314 113.486,12.3611C112.106,12.4081 111.026,13.5649 111.073,14.9448C111.253,20.2263 113.435,23.7827 116.293,25.9488C119.044,28.0336 122.25,28.7059 124.465,28.6536C125.846,28.621 126.938,27.4756 126.906,26.0953Z"
android:fillColor="#DADCE0"/>
<path
android:pathData="M128.481,18.363C128.448,16.9826 127.303,15.8901 125.922,15.9227C125.7,15.928 125.212,15.8357 124.824,15.5417C124.543,15.3289 124.141,14.8922 124.103,13.7742C124.056,12.3943 122.899,11.3138 121.519,11.3608C120.14,11.4079 119.059,12.5647 119.106,13.9446C119.194,16.5092 120.278,18.3704 121.804,19.5266C123.222,20.6015 124.86,20.9492 126.041,20.9213C127.421,20.8887 128.513,19.7433 128.481,18.363Z"
android:fillColor="#DADCE0"/>
<path
android:pathData="M96.7117,94.8594C96.8874,94.8598 97.0613,94.8238 97.2226,94.7538C97.384,94.6838 97.5294,94.5812 97.65,94.4524C97.7705,94.3236 97.8636,94.1713 97.9235,94.0048C97.9835,93.8384 98.009,93.6613 97.9984,93.4845C97.3551,82.5242 89.2298,73.8597 79.2838,73.8597C77.0243,73.8478 74.7851,74.2887 72.696,75.1568C70.7339,75.9851 68.628,76.4117 66.5007,76.4117C64.3735,76.4117 62.2675,75.9851 60.3054,75.1568C58.2164,74.2887 55.9771,73.8478 53.7177,73.8597C43.7717,73.8597 35.64,82.5242 35.0031,93.4845C34.9925,93.6613 35.018,93.8384 35.0779,94.0048C35.1378,94.1713 35.2309,94.3236 35.3515,94.4524C35.472,94.5812 35.6175,94.6838 35.7788,94.7538C35.9402,94.8238 36.1141,94.8598 36.2897,94.8594L96.7117,94.8594Z"
android:fillColor="#9AA0A6"/>
<path
android:pathData="M65.0179,94.8594C65.1518,94.8598 65.2842,94.8238 65.4072,94.7538C65.5301,94.6838 65.6409,94.5812 65.7328,94.4524C65.8246,94.3236 65.8955,94.1713 65.9412,94.0048C65.9869,93.8384 66.0063,93.6613 65.9982,93.4845C65.5081,82.5242 59.3174,73.8597 51.7395,73.8597C50.018,73.8478 48.3119,74.2887 46.7202,75.1568C45.2253,75.9851 43.6207,76.4117 42.0,76.4117C40.3793,76.4117 38.7747,75.9851 37.2798,75.1568C35.6881,74.2887 33.982,73.8478 32.2605,73.8597C24.6826,73.8597 18.487,82.5242 18.0018,93.4845C17.9937,93.6613 18.0131,93.8384 18.0588,94.0048C18.1045,94.1713 18.1754,94.3236 18.2672,94.4524C18.3591,94.5812 18.4699,94.6838 18.5928,94.7538C18.7158,94.8238 18.8482,94.8598 18.9821,94.8594L65.0179,94.8594Z"
android:fillColor="#BDC1C6"/>
<path
android:pathData="M45.0007,66.8594C48.8667,66.8594 52.0007,63.5016 52.0007,59.3594C52.0007,55.2173 48.8667,51.8594 45.0007,51.8594C41.1347,51.8594 38.0007,55.2173 38.0007,59.3594C38.0007,63.5016 41.1347,66.8594 45.0007,66.8594Z"
android:fillColor="#2A2952"/>
<path
android:pathData="M66.4193,73.6966C58.4561,73.6966 52.0007,67.2412 52.0007,59.278C52.0007,51.3149 58.4561,44.8594 66.4193,44.8594C74.3825,44.8594 80.8379,51.3149 80.8379,59.278C80.8379,67.2412 74.3825,73.6966 66.4193,73.6966Z"
android:fillColor="#9AA0A6"/>
<path
android:pathData="M42.4186,73.6966C34.4554,73.6966 28.0,67.2412 28.0,59.278C28.0,51.3149 34.4554,44.8594 42.4186,44.8594C50.3818,44.8594 56.8372,51.3149 56.8372,59.278C56.8372,67.2412 50.3818,73.6966 42.4186,73.6966Z"
android:fillColor="#BDC1C6"/>
<path
android:pathData="M105.96,57.595C110.653,57.7207 114.559,54.0185 114.685,49.3257L114.685,49.3257C114.811,44.633 111.108,40.7268 106.416,40.6011L106.416,40.6011C101.723,40.4753 97.8166,44.1776 97.6909,48.8703L97.6909,48.8703C97.5651,53.563 101.267,57.4692 105.96,57.595L105.96,57.595Z"
android:fillColor="#4285F4"/>
<path
android:pathData="M88.5558,35.1209C93.2485,35.2466 97.1547,31.5444 97.2805,26.8516L97.2805,26.8516C97.4062,22.1589 93.704,18.2527 89.0112,18.127L89.0112,18.127C84.3185,18.0012 80.4123,21.7034 80.2866,26.3962L80.2866,26.3962C80.1608,31.0889 83.863,34.9951 88.5558,35.1209L88.5558,35.1209Z"
android:fillColor="#4285F4"/>
<path
android:pathData="M89.3727,50.6961C94.7613,55.4583 101.345,57.3574 105.886,57.592L106.195,51.6C102.802,51.4247 97.572,49.935 93.3459,46.2002C89.2407,42.5723 85.8768,36.6527 86.2704,27.0988L80.2755,26.8518C79.8104,38.1413 83.863,45.8271 89.3727,50.6961Z"
android:fillColor="#4285F4"/>
</vector>

View File

@@ -0,0 +1,81 @@
<!--
Copyright (C) 2020 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="149.0dp"
android:height="106.0dp"
android:viewportWidth="149.0"
android:viewportHeight="106.0">
<path
android:pathData="M92.711,94.8594C92.8867,94.8598 93.0605,94.8238 93.2219,94.7538C93.3833,94.6838 93.5287,94.5812 93.6492,94.4524C93.7698,94.3236 93.8629,94.1713 93.9228,94.0048C93.9827,93.8384 94.0082,93.6613 93.9977,93.4845C93.3543,82.5242 85.229,73.8597 75.2831,73.8597C73.0236,73.8478 70.7843,74.2887 68.6953,75.1568C66.7332,75.9851 64.6272,76.4117 62.5,76.4117C60.3728,76.4117 58.2668,75.9851 56.3047,75.1568C54.2157,74.2887 51.9764,73.8478 49.7169,73.8597C39.771,73.8597 31.6392,82.5242 31.0023,93.4845C30.9918,93.6613 31.0173,93.8384 31.0772,94.0048C31.1371,94.1713 31.2302,94.3236 31.3508,94.4524C31.4713,94.5812 31.6167,94.6838 31.7781,94.7538C31.9395,94.8238 32.1133,94.8598 32.289,94.8594L92.711,94.8594Z"
android:fillColor="#34A853"/>
<path
android:pathData="M63.0,44.8594C66.7401,44.9399 70.3003,46.5029 72.9173,49.2134C75.5344,51.9239 77.0,55.5662 77.0,59.3594C77.0,63.1527 75.5344,66.795 72.9173,69.5055C70.3003,72.216 66.7401,73.779 63.0,73.8594L63.0,44.8594Z"
android:fillColor="#AF735B"/>
<path
android:pathData="M78.0,51.3412L75.6967,55.8594L74.0,50.8594L78.0,51.3412Z"
android:fillColor="#AF735B"/>
<path
android:pathData="M63.0,73.8594C58.9927,73.779 55.1783,72.216 52.3743,69.5055C49.5703,66.795 48.0,63.1527 48.0,59.3594C48.0,55.5662 49.5703,51.9239 52.3743,49.2134C55.1783,46.5029 58.9927,44.9399 63.0,44.8594L63.0,73.8594Z"
android:fillColor="#2A2952"/>
<path
android:pathData="M76.4697,52.3898L69.4697,45.3898L70.5303,44.3291L77.5303,51.3291L76.4697,52.3898Z"
android:fillColor="#2A2952"/>
<path
android:pathData="M61.4932,59.3066L73.4932,48.3066L74.5068,49.4123L62.5068,60.4123L61.4932,59.3066Z"
android:fillColor="#2A2952"/>
<path
android:pathData="M60.0001,59.8823C59.9971,59.4613 60.0827,59.0444 60.2514,58.6587C60.4201,58.2729 60.6682,57.927 60.9794,57.6433C61.2906,57.3596 61.6581,57.1445 62.0579,57.012C62.4577,56.8795 62.881,56.8325 63.3001,56.8742C64.055,56.9704 64.7478,57.3415 65.2459,57.9165C65.744,58.4914 66.0123,59.2298 65.9996,59.9902L65.9996,62.7286C66.0123,63.489 65.744,64.2274 65.2459,64.8024C64.7478,65.3774 64.055,65.7485 63.3001,65.8447C62.8844,65.886 62.4645,65.8402 62.0675,65.7101C61.6705,65.58 61.305,65.3685 60.9944,65.0892C60.6838,64.8099 60.435,64.4688 60.2637,64.0879C60.0925,63.707 60.0027,63.2946 60.0001,62.877L60.0001,59.8823Z"
android:fillColor="#AF735B"/>
<path
android:pathData="M41.0,66.8594C44.866,66.8594 48.0,63.5016 48.0,59.3594C48.0,55.2173 44.866,51.8594 41.0,51.8594C37.134,51.8594 34.0,55.2173 34.0,59.3594C34.0,63.5016 37.134,66.8594 41.0,66.8594Z"
android:fillColor="#2A2952"/>
<path
android:pathData="M19.3165,94.853C19.1171,94.8538 18.9202,94.8096 18.7406,94.7235C18.5611,94.6375 18.4037,94.512 18.2804,94.3566C18.1572,94.2012 18.0713,94.02 18.0293,93.8267C17.9874,93.6334 17.9905,93.4332 18.0383,93.2413C20.6603,82.6935 30.1452,74.3944 39.912,74.3944C49.823,74.3944 56.4041,82.9405 55.0276,93.7092C54.9905,94.0274 54.8361,94.3208 54.5942,94.5331C54.3522,94.7454 54.0397,94.8616 53.7166,94.8595L19.3165,94.853Z"
android:fillColor="#FBBC05"/>
<path
android:pathData="M41.7209,74.3944C33.7578,74.3944 27.3023,67.939 27.3023,59.9758C27.3023,52.0126 33.7578,45.5572 41.7209,45.5572C49.6841,45.5572 56.1395,52.0126 56.1395,59.9758C56.1395,67.939 49.6841,74.3944 41.7209,74.3944Z"
android:fillColor="#D59E91"/>
<path
android:pathData="M27.3023,59.5107C24.8352,59.5107 22.4691,60.5455 20.7246,62.3875C18.9801,64.2295 18.0,66.7278 18.0,69.3327L18.0,73.0553C18.0,73.4105 18.1336,73.7511 18.3714,74.0022C18.6093,74.2533 18.9319,74.3944 19.2682,74.3944L26.0341,74.3944C26.3705,74.3944 26.693,74.2533 26.9309,74.0022C27.1687,73.7511 27.3023,73.4105 27.3023,73.0553L27.3023,59.5107Z"
android:fillColor="#D9DBDF"/>
<path
android:pathData="M57.4766,55.1029L53.3488,53.9293L54.7525,59.5107L57.7779,56.2901C57.8692,56.2061 57.9365,56.0964 57.9719,55.9736C58.0072,55.8507 58.0093,55.7197 57.9778,55.5957C57.9463,55.4716 57.8826,55.3596 57.7939,55.2724C57.7053,55.1852 57.5953,55.1264 57.4766,55.1029L57.4766,55.1029Z"
android:fillColor="#D59E91"/>
<path
android:pathData="M41.2558,45.5572C41.2558,49.5046 39.7857,53.2903 37.1689,56.0816C34.5521,58.8728 31.003,60.4409 27.3023,60.4409C27.3023,56.4935 28.7724,52.7078 31.3892,49.9165C34.006,47.1253 37.5551,45.5572 41.2558,45.5572L41.2558,45.5572Z"
android:fillColor="#D9DBDF"/>
<path
android:pathData="M49.92,60.8349C51.1333,62.8 52.9194,64.2407 54.9884,64.8785L55.4303,63.4451C53.7411,62.9244 52.2376,61.7334 51.1963,60.0469L49.92,60.8349Z"
android:fillColor="#606368"/>
<path
android:pathData="M126.836,34.3968C126.803,33.0165 125.657,31.924 124.277,31.9566C122.033,32.0096 118.483,31.2834 115.492,29.017C112.609,26.8319 110.065,23.0845 109.846,16.6608C109.799,15.2808 108.642,14.2003 107.262,14.2474C105.882,14.2944 104.802,15.4512 104.849,16.8311C105.117,24.7016 108.344,29.8735 112.472,33.0019C116.493,36.0492 121.194,37.0308 124.395,36.9552C125.776,36.9226 126.868,35.7772 126.836,34.3968Z"
android:fillColor="#DADCE0"/>
<path
android:pathData="M128.906,27.0953C128.873,25.7149 127.728,24.6224 126.347,24.655C125.089,24.6847 123.034,24.2678 121.313,22.9639C119.7,21.7412 118.201,19.6093 118.07,15.7745C118.023,14.3946 116.866,13.314 115.486,13.3611C114.106,13.4081 113.026,14.5649 113.073,15.9448C113.253,21.2263 115.435,24.7827 118.293,26.9488C121.044,29.0336 124.25,29.7059 126.465,29.6536C127.846,29.621 128.938,28.4756 128.906,27.0953Z"
android:fillColor="#DADCE0"/>
<path
android:pathData="M130.481,19.363C130.448,17.9826 129.303,16.8901 127.923,16.9227C127.7,16.928 127.212,16.8357 126.824,16.5417C126.543,16.3289 126.141,15.8922 126.103,14.7742C126.056,13.3943 124.899,12.3138 123.519,12.3608C122.14,12.4079 121.059,13.5647 121.106,14.9446C121.194,17.5092 122.278,19.3704 123.804,20.5266C125.222,21.6015 126.86,21.9492 128.041,21.9213C129.421,21.8887 130.513,20.7433 130.481,19.363Z"
android:fillColor="#DADCE0"/>
<path
android:pathData="M107.96,58.595C112.653,58.7207 116.559,55.0185 116.685,50.3257L116.685,50.3257C116.811,45.633 113.108,41.7268 108.416,41.6011L108.416,41.6011C103.723,41.4753 99.8166,45.1776 99.6909,49.8703L99.6909,49.8703C99.5651,54.563 103.267,58.4692 107.96,58.595L107.96,58.595Z"
android:fillColor="#4285F4"/>
<path
android:pathData="M90.5558,36.1209C95.2485,36.2466 99.1547,32.5444 99.2805,27.8516L99.2805,27.8516C99.4062,23.1589 95.704,19.2527 91.0112,19.127L91.0112,19.127C86.3185,19.0012 82.4123,22.7034 82.2866,27.3962L82.2866,27.3962C82.1608,32.0889 85.863,35.9951 90.5558,36.1209L90.5558,36.1209Z"
android:fillColor="#4285F4"/>
<path
android:pathData="M91.3727,51.6961C96.7613,56.4583 103.345,58.3574 107.886,58.592L108.195,52.6C104.802,52.4247 99.572,50.935 95.3459,47.2002C91.2407,43.5723 87.8768,37.6527 88.2704,28.0988L82.2755,27.8518C81.8104,39.1413 85.863,46.8271 91.3727,51.6961Z"
android:fillColor="#4285F4"/>
</vector>

View File

@@ -0,0 +1,39 @@
<!--
Copyright (C) 2020 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="149.0dp"
android:height="106.0dp"
android:viewportWidth="149.0"
android:viewportHeight="106.0">
<path
android:pathData="M105.975,51.3487C105.931,49.4783 104.379,47.9979 102.508,48.0421C99.4675,48.1139 94.6568,47.1298 90.6046,44.0588C86.6976,41.0979 83.2499,36.02 82.9531,27.3155C82.8894,25.4457 81.3219,23.9815 79.4521,24.0453C77.5822,24.109 76.1181,25.6765 76.1818,27.5463C76.5454,38.2112 80.9186,45.2194 86.5123,49.4586C91.9607,53.5877 98.3304,54.9179 102.668,54.8154C104.539,54.7712 106.019,53.2191 105.975,51.3487Z"
android:fillColor="#DADCE0"/>
<path
android:pathData="M108.78,41.4548C108.736,39.5844 107.184,38.1039 105.313,38.1481C103.609,38.1884 100.823,37.6235 98.4918,35.8566C96.3056,34.1997 94.2744,31.3109 94.0973,26.1146C94.0335,24.2447 92.466,22.7806 90.5962,22.8443C88.7263,22.9081 87.2622,24.4755 87.3259,26.3454C87.5699,33.502 90.5266,38.3212 94.3995,41.2563C98.1272,44.0814 102.472,44.9924 105.473,44.9215C107.344,44.8773 108.824,43.3252 108.78,41.4548Z"
android:fillColor="#DADCE0"/>
<path
android:pathData="M110.915,30.9772C110.87,29.1068 109.318,27.6263 107.448,27.6705C107.146,27.6777 106.485,27.5526 105.96,27.1542C105.579,26.8658 105.034,26.2741 104.983,24.7592C104.919,22.8893 103.352,21.4252 101.482,21.489C99.6118,21.5527 98.1477,23.1202 98.2114,24.99C98.3299,28.4653 99.8001,30.9873 101.867,32.5539C103.789,34.0105 106.009,34.4816 107.608,34.4439C109.478,34.3997 110.959,32.8476 110.915,30.9772Z"
android:fillColor="#DADCE0"/>
<path
android:pathData="M80.3979,84.1388C86.7568,84.3092 92.0498,79.2924 92.2203,72.9336L92.2203,72.9336C92.3907,66.5747 87.3739,61.2816 81.0151,61.1112L81.0151,61.1112C74.6562,60.9408 69.3631,65.9575 69.1927,72.3164L69.1927,72.3164C69.0223,78.6753 74.039,83.9683 80.3979,84.1388L80.3979,84.1388Z"
android:fillColor="#4285F4"/>
<path
android:pathData="M56.8143,53.685C63.1732,53.8554 68.4662,48.8386 68.6366,42.4798L68.6366,42.4798C68.8071,36.1209 63.7903,30.8278 57.4314,30.6574L57.4314,30.6574C51.0726,30.487 45.7795,35.5037 45.6091,41.8626L45.6091,41.8626C45.4387,48.2215 50.4554,53.5145 56.8143,53.685L56.8143,53.685Z"
android:fillColor="#4285F4"/>
<path
android:pathData="M57.9211,74.7903C65.223,81.2433 74.1437,83.8166 80.2969,84.1345L80.7165,76.0151C76.1182,75.7775 69.0316,73.759 63.305,68.6981C57.7423,63.7821 53.1841,55.7607 53.7174,42.8147L45.594,42.4801C44.9638,57.7778 50.4553,68.1924 57.9211,74.7903Z"
android:fillColor="#4285F4"/>
</vector>

View File

@@ -0,0 +1,69 @@
<!--
Copyright (C) 2020 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="149.0dp"
android:height="106.0dp"
android:viewportWidth="149.0"
android:viewportHeight="106.0">
<path
android:pathData="M111.836,30.3968C111.803,29.0164 110.657,27.9239 109.277,27.9565C107.033,28.0095 103.483,27.2833 100.492,25.017C97.6091,22.8319 95.0647,19.0845 94.8457,12.6607C94.7987,11.2808 93.6419,10.2003 92.262,10.2473C90.8821,10.2944 89.8016,11.4511 89.8486,12.831C90.1169,20.7015 93.3443,25.8734 97.4723,29.0019C101.493,32.0491 106.194,33.0307 109.395,32.9551C110.776,32.9225 111.868,31.7771 111.836,30.3968Z"
android:fillColor="#DADCE0"/>
<path
android:pathData="M113.906,23.0952C113.873,21.7149 112.728,20.6223 111.347,20.6549C110.089,20.6847 108.033,20.2678 106.313,18.9638C104.7,17.7411 103.201,15.6092 103.07,11.7744C103.023,10.3945 101.866,9.31399 100.486,9.36103C99.1062,9.40807 98.0257,10.5648 98.0728,11.9448C98.2528,17.2262 100.435,20.7827 103.293,22.9487C106.044,25.0336 109.25,25.7059 111.465,25.6535C112.846,25.6209 113.938,24.4755 113.906,23.0952Z"
android:fillColor="#DADCE0"/>
<path
android:pathData="M115.481,15.363C115.448,13.9826 114.303,12.8901 112.923,12.9227C112.7,12.928 112.212,12.8357 111.824,12.5417C111.543,12.3289 111.141,11.8922 111.103,10.7742C111.056,9.3943 109.899,8.3138 108.519,8.36084C107.14,8.40788 106.059,9.56465 106.106,10.9446C106.194,13.5092 107.278,15.3704 108.804,16.5266C110.222,17.6015 111.86,17.9492 113.041,17.9213C114.421,17.8887 115.513,16.7433 115.481,15.363Z"
android:fillColor="#DADCE0"/>
<path
android:pathData="M81.711,91.8593C81.8867,91.8596 82.0605,91.8236 82.2219,91.7536C82.3833,91.6836 82.5287,91.5811 82.6492,91.4522C82.7698,91.3234 82.8629,91.1711 82.9228,91.0046C82.9827,90.8382 83.0082,90.6611 82.9977,90.4843C82.3543,79.524 74.229,70.8595 64.2831,70.8595C62.0236,70.8477 59.7843,71.2886 57.6953,72.1566C55.7332,72.9849 53.6272,73.4115 51.5,73.4115C49.3728,73.4115 47.2668,72.9849 45.3047,72.1566C43.2157,71.2886 40.9764,70.8477 38.7169,70.8595C28.771,70.8595 20.6392,79.524 20.0023,90.4843C19.9918,90.6611 20.0173,90.8382 20.0772,91.0046C20.1371,91.1711 20.2302,91.3234 20.3508,91.4522C20.4713,91.5811 20.6167,91.6836 20.7781,91.7536C20.9395,91.8236 21.1133,91.8596 21.289,91.8593L81.711,91.8593Z"
android:fillColor="#34A853"/>
<path
android:pathData="M52.0,41.8593C55.7401,41.9397 59.3003,43.5027 61.9173,46.2132C64.5344,48.9237 66.0,52.566 66.0,56.3593C66.0,60.1525 64.5344,63.7948 61.9173,66.5053C59.3003,69.2158 55.7401,70.7788 52.0,70.8593L52.0,41.8593Z"
android:fillColor="#AF735B"/>
<path
android:pathData="M67.0,48.341L64.6967,52.8593L63.0,47.8593L67.0,48.341Z"
android:fillColor="#AF735B"/>
<path
android:pathData="M52.0,70.8593C47.9927,70.7788 44.1783,69.2158 41.3743,66.5053C38.5703,63.7948 37.0,60.1525 37.0,56.3593C37.0,52.566 38.5703,48.9237 41.3743,46.2132C44.1783,43.5027 47.9927,41.9397 52.0,41.8593L52.0,70.8593Z"
android:fillColor="#2A2952"/>
<path
android:pathData="M65.4697,49.3896L58.4697,42.3896L59.5303,41.3289L66.5303,48.3289L65.4697,49.3896Z"
android:fillColor="#2A2952"/>
<path
android:pathData="M50.4932,56.3064L62.4932,45.3064L63.5068,46.4121L51.5068,57.4121L50.4932,56.3064Z"
android:fillColor="#2A2952"/>
<path
android:pathData="M49.0001,56.8821C48.9971,56.4612 49.0827,56.0443 49.2514,55.6585C49.4201,55.2728 49.6682,54.9268 49.9794,54.6431C50.2906,54.3594 50.6581,54.1443 51.0579,54.0118C51.4577,53.8793 51.881,53.8323 52.3001,53.874C53.055,53.9702 53.7478,54.3413 54.2459,54.9163C54.744,55.4912 55.0123,56.2296 54.9996,56.9901L54.9996,59.7284C55.0123,60.4889 54.744,61.2273 54.2459,61.8022C53.7478,62.3772 53.055,62.7483 52.3001,62.8445C51.8844,62.8858 51.4645,62.84 51.0675,62.7099C50.6705,62.5798 50.305,62.3683 49.9944,62.089C49.6838,61.8097 49.435,61.4687 49.2637,61.0878C49.0925,60.7068 49.0027,60.2944 49.0001,59.8768L49.0001,56.8821Z"
android:fillColor="#AF735B"/>
<path
android:pathData="M30.0,63.8593C33.866,63.8593 37.0,60.5014 37.0,56.3593C37.0,52.2171 33.866,48.8593 30.0,48.8593C26.134,48.8593 23.0,52.2171 23.0,56.3593C23.0,60.5014 26.134,63.8593 30.0,63.8593Z"
android:fillColor="#2A2952"/>
<path
android:pathData="M63.3654,97.1463L62.0966,95.9913C57.5904,91.905 54.6154,89.21 54.6154,85.9025C54.6154,83.2075 56.7329,81.09 59.4279,81.09C60.9504,81.09 62.4116,81.7988 63.3654,82.9188C64.3191,81.7988 65.7804,81.09 67.3029,81.09C69.9979,81.09 72.1154,83.2075 72.1154,85.9025C72.1154,89.21 69.1404,91.905 64.6341,96.0L63.3654,97.1463Z"
android:fillColor="#FF0000"/>
<path
android:pathData="M59.4279,81.59C57.009,81.59 55.1154,83.4837 55.1154,85.9025C55.1154,87.392 55.7807,88.7826 57.0532,90.3383C58.3313,91.901 60.1693,93.5686 62.4325,95.6209L63.3666,96.4713L64.2978,95.63L64.2989,95.629L64.3056,95.623C66.5653,93.5694 68.4006,91.9017 69.6774,90.3395C70.95,88.7827 71.6154,87.392 71.6154,85.9025C71.6154,83.4837 69.7217,81.59 67.3029,81.59C65.9318,81.59 64.608,82.2307 63.746,83.2429L63.3654,83.69L62.9847,83.2429C62.1227,82.2307 60.799,81.59 59.4279,81.59ZM54.1154,85.9025C54.1154,82.9314 56.4567,80.59 59.4279,80.59C60.9099,80.59 62.3329,81.1989 63.3654,82.1906C64.3978,81.1989 65.8209,80.59 67.3029,80.59C70.274,80.59 72.6154,82.9314 72.6154,85.9025C72.6154,87.7205 71.7932,89.3311 70.4517,90.9724C69.1278,92.5921 67.247,94.3012 65.0299,96.316L64.9704,96.3701L64.9693,96.371L63.3641,97.8213L61.7607,96.3617L61.7237,96.3281C59.4967,94.3087 57.6076,92.5957 56.2791,90.9714C54.9375,89.3312 54.1154,87.7205 54.1154,85.9025Z"
android:fillColor="#FFFFFF"/>
<path
android:pathData="M92.9601,54.5949C97.6528,54.7207 101.559,51.0184 101.685,46.3257L101.685,46.3257C101.811,41.6329 98.1083,37.7268 93.4155,37.601L93.4155,37.601C88.7228,37.4752 84.8166,41.1775 84.6909,45.8702L84.6909,45.8702C84.5651,50.563 88.2673,54.4691 92.9601,54.5949L92.9601,54.5949Z"
android:fillColor="#4285F4"/>
<path
android:pathData="M75.5558,32.1208C80.2485,32.2466 84.1547,28.5443 84.2805,23.8516L84.2805,23.8516C84.4062,19.1588 80.704,15.2527 76.0112,15.1269L76.0112,15.1269C71.3185,15.0011 67.4123,18.7034 67.2866,23.3961L67.2866,23.3961C67.1608,28.0889 70.863,31.995 75.5558,32.1208L75.5558,32.1208Z"
android:fillColor="#4285F4"/>
<path
android:pathData="M76.3727,47.6961C81.7613,52.4583 88.3447,54.3573 92.8856,54.592L93.1953,48.6C89.8018,48.4246 84.572,46.935 80.3459,43.2002C76.2407,39.5722 72.8768,33.6526 73.2704,24.0987L67.2755,23.8517C66.8104,35.1412 70.863,42.827 76.3727,47.6961Z"
android:fillColor="#4285F4"/>
</vector>

View File

@@ -0,0 +1,45 @@
<!--
Copyright (C) 2020 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="149.0dp"
android:height="106.0dp"
android:viewportWidth="149.0"
android:viewportHeight="106.0">
<path
android:pathData="M133.0,17.0L122.0,17.0L122.0,29.0L133.0,29.0L133.0,17.0Z"
android:fillColor="#E7E9EC"/>
<path
android:pathData="M121.916,35.0L98.0884,35.0C96.6326,34.9992 95.1908,35.296 93.8455,35.8735C92.5003,36.4511 91.2778,37.298 90.2481,38.366C89.2184,39.4339 88.4015,40.702 87.8442,42.0976C87.2869,43.4933 87.0,44.9893 87.0,46.5L87.0,58.0L121.629,58.0C127.859,58.0 133.11,52.7251 132.998,46.2802C132.943,43.2685 131.751,40.3996 129.678,38.2902C127.606,36.1808 124.819,34.9995 121.916,35.0L121.916,35.0Z"
android:fillColor="#437CF6"/>
<path
android:pathData="M64.0,18.5C64.0,12.701 68.701,8.0 74.5,8.0L122.5,8.0C128.299,8.0 133.0,12.701 133.0,18.5L133.0,18.5C133.0,24.299 128.299,29.0 122.5,29.0L74.5,29.0C68.701,29.0 64.0,24.299 64.0,18.5L64.0,18.5Z"
android:fillColor="#E7E9EC"/>
<path
android:pathData="M94.7117,98.0C94.8874,98.0003 95.0613,97.9644 95.2226,97.8944C95.384,97.8244 95.5294,97.7218 95.65,97.593C95.7705,97.4642 95.8636,97.3119 95.9235,97.1454C95.9835,96.9789 96.009,96.8019 95.9984,96.6251C95.3551,85.6647 87.2298,77.0002 77.2838,77.0002C75.0243,76.9884 72.7851,77.4293 70.696,78.2973C68.7339,79.1257 66.628,79.5523 64.5007,79.5523C62.3735,79.5523 60.2675,79.1257 58.3054,78.2973C56.2164,77.4293 53.9771,76.9884 51.7177,77.0002C41.7717,77.0002 33.64,85.6647 33.0031,96.6251C32.9925,96.8019 33.018,96.9789 33.0779,97.1454C33.1378,97.3119 33.2309,97.4642 33.3515,97.593C33.472,97.7218 33.6175,97.8244 33.7788,97.8944C33.9402,97.9644 34.1141,98.0003 34.2897,98.0L94.7117,98.0Z"
android:fillColor="#9AA0A6"/>
<path
android:pathData="M63.0179,98.0C63.1518,98.0003 63.2842,97.9644 63.4072,97.8944C63.5301,97.8244 63.6409,97.7218 63.7328,97.593C63.8246,97.4642 63.8955,97.3119 63.9412,97.1454C63.9869,96.9789 64.0063,96.8019 63.9982,96.6251C63.5081,85.6647 57.3174,77.0002 49.7395,77.0002C48.018,76.9884 46.3119,77.4293 44.7202,78.2973C43.2253,79.1257 41.6207,79.5523 40.0,79.5523C38.3793,79.5523 36.7747,79.1257 35.2798,78.2973C33.6881,77.4293 31.982,76.9884 30.2605,77.0002C22.6826,77.0002 16.487,85.6647 16.0018,96.6251C15.9937,96.8019 16.0131,96.9789 16.0588,97.1454C16.1045,97.3119 16.1754,97.4642 16.2672,97.593C16.3591,97.7218 16.4699,97.8244 16.5928,97.8944C16.7158,97.9644 16.8482,98.0003 16.9821,98.0L63.0179,98.0Z"
android:fillColor="#BDC1C6"/>
<path
android:pathData="M43.0007,70.0C46.8667,70.0 50.0007,66.6421 50.0007,62.5C50.0007,58.3579 46.8667,55.0 43.0007,55.0C39.1347,55.0 36.0007,58.3579 36.0007,62.5C36.0007,66.6421 39.1347,70.0 43.0007,70.0Z"
android:fillColor="#2A2952"/>
<path
android:pathData="M64.4193,76.8372C56.4561,76.8372 50.0007,70.3818 50.0007,62.4186C50.0007,54.4554 56.4561,48.0 64.4193,48.0C72.3825,48.0 78.8379,54.4554 78.8379,62.4186C78.8379,70.3818 72.3825,76.8372 64.4193,76.8372Z"
android:fillColor="#9AA0A6"/>
<path
android:pathData="M40.4186,76.8372C32.4554,76.8372 26.0,70.3818 26.0,62.4186C26.0,54.4554 32.4554,48.0 40.4186,48.0C48.3818,48.0 54.8372,54.4554 54.8372,62.4186C54.8372,70.3818 48.3818,76.8372 40.4186,76.8372Z"
android:fillColor="#BDC1C6"/>
</vector>

View File

@@ -0,0 +1,72 @@
<!--
Copyright (C) 2020 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="149.0dp"
android:height="106.0dp"
android:viewportWidth="149.0"
android:viewportHeight="106.0">
<path
android:pathData="M131.0,17.0L120.0,17.0L120.0,29.0L131.0,29.0L131.0,17.0Z"
android:fillColor="#E7E9EC"/>
<path
android:pathData="M119.916,35.0L96.0884,35.0C94.6326,34.9992 93.1908,35.296 91.8455,35.8735C90.5003,36.4511 89.2778,37.298 88.2481,38.366C87.2184,39.4339 86.4015,40.702 85.8442,42.0976C85.2869,43.4933 85.0,44.9893 85.0,46.5L85.0,58.0L119.629,58.0C125.859,58.0 131.11,52.7251 130.998,46.2802C130.943,43.2685 129.751,40.3996 127.678,38.2902C125.606,36.1808 122.819,34.9995 119.916,35.0L119.916,35.0Z"
android:fillColor="#437CF6"/>
<path
android:pathData="M92.711,98.0C92.8867,98.0003 93.0605,97.9644 93.2219,97.8944C93.3833,97.8244 93.5287,97.7218 93.6492,97.593C93.7698,97.4642 93.8629,97.3119 93.9228,97.1454C93.9827,96.9789 94.0082,96.8019 93.9977,96.6251C93.3543,85.6647 85.229,77.0002 75.2831,77.0002C73.0236,76.9884 70.7843,77.4293 68.6953,78.2973C66.7332,79.1257 64.6272,79.5523 62.5,79.5523C60.3728,79.5523 58.2668,79.1257 56.3047,78.2973C54.2157,77.4293 51.9764,76.9884 49.7169,77.0002C39.771,77.0002 31.6392,85.6647 31.0023,96.6251C30.9918,96.8019 31.0173,96.9789 31.0772,97.1454C31.1371,97.3119 31.2302,97.4642 31.3508,97.593C31.4713,97.7218 31.6167,97.8244 31.7781,97.8944C31.9395,97.9644 32.1133,98.0003 32.289,98.0L92.711,98.0Z"
android:fillColor="#34A853"/>
<path
android:pathData="M63.0,48.0C66.7401,48.0804 70.3003,49.6434 72.9173,52.354C75.5344,55.0645 77.0,58.7068 77.0,62.5C77.0,66.2932 75.5344,69.9355 72.9173,72.646C70.3003,75.3566 66.7401,76.9196 63.0,77.0L63.0,48.0Z"
android:fillColor="#AF735B"/>
<path
android:pathData="M78.0,54.4818L75.6967,59.0L74.0,54.0L78.0,54.4818Z"
android:fillColor="#AF735B"/>
<path
android:pathData="M63.0,77.0C58.9927,76.9196 55.1783,75.3566 52.3743,72.646C49.5703,69.9355 48.0,66.2932 48.0,62.5C48.0,58.7068 49.5703,55.0645 52.3743,52.354C55.1783,49.6434 58.9927,48.0804 63.0,48.0L63.0,77.0Z"
android:fillColor="#2A2952"/>
<path
android:pathData="M76.4697,55.5304L69.4697,48.5304L70.5303,47.4697L77.5303,54.4697L76.4697,55.5304Z"
android:fillColor="#2A2952"/>
<path
android:pathData="M61.4932,62.4471L73.4932,51.4471L74.5068,52.5529L62.5068,63.5529L61.4932,62.4471Z"
android:fillColor="#2A2952"/>
<path
android:pathData="M60.0001,63.0229C59.9971,62.6019 60.0827,62.185 60.2514,61.7993C60.4201,61.4135 60.6682,61.0675 60.9794,60.7838C61.2906,60.5001 61.6581,60.285 62.0579,60.1525C62.4577,60.02 62.881,59.9731 63.3001,60.0147C64.055,60.1109 64.7478,60.482 65.2459,61.057C65.744,61.632 66.0123,62.3704 65.9996,63.1308L65.9996,65.8692C66.0123,66.6296 65.744,67.368 65.2459,67.943C64.7478,68.518 64.055,68.8891 63.3001,68.9853C62.8844,69.0266 62.4645,68.9807 62.0675,68.8506C61.6705,68.7205 61.305,68.5091 60.9944,68.2297C60.6838,67.9504 60.435,67.6094 60.2637,67.2285C60.0925,66.8476 60.0027,66.4351 60.0001,66.0176L60.0001,63.0229Z"
android:fillColor="#AF735B"/>
<path
android:pathData="M41.0,70.0C44.866,70.0 48.0,66.6421 48.0,62.5C48.0,58.3579 44.866,55.0 41.0,55.0C37.134,55.0 34.0,58.3579 34.0,62.5C34.0,66.6421 37.134,70.0 41.0,70.0Z"
android:fillColor="#2A2952"/>
<path
android:pathData="M62.0,18.5C62.0,12.701 66.701,8.0 72.5,8.0L120.5,8.0C126.299,8.0 131.0,12.701 131.0,18.5L131.0,18.5C131.0,24.299 126.299,29.0 120.5,29.0L72.5,29.0C66.701,29.0 62.0,24.299 62.0,18.5L62.0,18.5Z"
android:fillColor="#E7E9EC"/>
<path
android:pathData="M19.3165,97.9935C19.1171,97.9943 18.9202,97.9501 18.7406,97.864C18.5611,97.778 18.4037,97.6525 18.2804,97.4971C18.1572,97.3417 18.0713,97.1605 18.0293,96.9672C17.9874,96.7739 17.9905,96.5737 18.0383,96.3818C20.6603,85.834 30.1452,77.5349 39.912,77.5349C49.823,77.5349 56.4041,86.081 55.0276,96.8497C54.9905,97.1679 54.8361,97.4613 54.5942,97.6736C54.3522,97.8859 54.0397,98.0021 53.7166,98.0L19.3165,97.9935Z"
android:fillColor="#FBBC05"/>
<path
android:pathData="M41.7209,77.535C33.7578,77.535 27.3023,71.0795 27.3023,63.1164C27.3023,55.1532 33.7578,48.6978 41.7209,48.6978C49.6841,48.6978 56.1395,55.1532 56.1395,63.1164C56.1395,71.0795 49.6841,77.535 41.7209,77.535Z"
android:fillColor="#D59E91"/>
<path
android:pathData="M27.3023,62.6512C24.8352,62.6512 22.4691,63.6861 20.7246,65.5281C18.9801,67.3701 18.0,69.8683 18.0,72.4733L18.0,76.1959C18.0,76.551 18.1336,76.8916 18.3714,77.1428C18.6093,77.3939 18.9319,77.535 19.2682,77.535L26.0341,77.535C26.3705,77.535 26.693,77.3939 26.9309,77.1428C27.1687,76.8916 27.3023,76.551 27.3023,76.1959L27.3023,62.6512Z"
android:fillColor="#D9DBDF"/>
<path
android:pathData="M57.4766,58.2434L53.3488,57.0698L54.7525,62.6512L57.7779,59.4307C57.8692,59.3467 57.9365,59.237 57.9719,59.1141C58.0072,58.9913 58.0093,58.8603 57.9778,58.7362C57.9463,58.6122 57.8826,58.5001 57.7939,58.4129C57.7053,58.3258 57.5953,58.267 57.4766,58.2434L57.4766,58.2434Z"
android:fillColor="#D59E91"/>
<path
android:pathData="M41.2558,48.6978C41.2558,52.6452 39.7857,56.4309 37.1689,59.2221C34.5521,62.0134 31.003,63.5815 27.3023,63.5815C27.3023,59.6341 28.7724,55.8483 31.3892,53.0571C34.006,50.2659 37.5551,48.6978 41.2558,48.6978L41.2558,48.6978Z"
android:fillColor="#D9DBDF"/>
<path
android:pathData="M49.92,63.9755C51.1333,65.9406 52.9194,67.3813 54.9884,68.0192L55.4303,66.5857C53.7411,66.065 52.2376,64.874 51.1963,63.1875L49.92,63.9755Z"
android:fillColor="#606368"/>
</vector>

View File

@@ -0,0 +1,30 @@
<!--
Copyright (C) 2020 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="149.0dp"
android:height="106.0dp"
android:viewportWidth="149.0"
android:viewportHeight="106.0">
<path
android:pathData="M126.0,32.6086L111.812,32.6086L111.812,48.0869L126.0,48.0869L126.0,32.6086Z"
android:fillColor="#E7E9EC"/>
<path
android:pathData="M111.703,55.8261L80.9691,55.8261C79.0913,55.825 77.2316,56.2078 75.4964,56.9528C73.7612,57.6977 72.1845,58.7902 70.8563,60.1677C69.5281,61.5452 68.4744,63.1808 67.7556,64.981C67.0367,66.7812 66.6667,68.7107 66.6667,70.6594L66.6667,85.4927L111.334,85.4927C119.369,85.4927 126.142,78.6889 125.998,70.3759C125.926,66.4912 124.389,62.7907 121.716,60.0699C119.043,57.3492 115.448,55.8253 111.703,55.8261L111.703,55.8261Z"
android:fillColor="#437CF6"/>
<path
android:pathData="M37.0,34.5435C37.0,27.0636 43.0636,21.0 50.5435,21.0L112.457,21.0C119.936,21.0 126.0,27.0636 126.0,34.5435L126.0,34.5435C126.0,42.0233 119.936,48.087 112.457,48.087L50.5435,48.087C43.0636,48.087 37.0,42.0233 37.0,34.5435L37.0,34.5435Z"
android:fillColor="#E7E9EC"/>
</vector>

View File

@@ -0,0 +1,60 @@
<!--
Copyright (C) 2020 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="149.0dp"
android:height="106.0dp"
android:viewportWidth="149.0"
android:viewportHeight="106.0">
<path
android:pathData="M124.0,15.0L113.0,15.0L113.0,27.0L124.0,27.0L124.0,15.0Z"
android:fillColor="#E7E9EC"/>
<path
android:pathData="M112.916,33.0L89.0884,33.0C87.6326,32.9992 86.1908,33.296 84.8455,33.8735C83.5003,34.4511 82.2778,35.298 81.2481,36.366C80.2184,37.4339 79.4015,38.702 78.8442,40.0976C78.2869,41.4933 78.0,42.9893 78.0,44.5L78.0,56.0L112.629,56.0C118.859,56.0 124.11,50.7251 123.998,44.2802C123.943,41.2685 122.751,38.3996 120.678,36.2902C118.606,34.1808 115.819,32.9995 112.916,33.0L112.916,33.0Z"
android:fillColor="#437CF6"/>
<path
android:pathData="M85.711,96.0C85.8867,96.0003 86.0605,95.9644 86.2219,95.8944C86.3833,95.8244 86.5287,95.7218 86.6492,95.593C86.7698,95.4642 86.8629,95.3119 86.9228,95.1454C86.9827,94.9789 87.0082,94.8019 86.9977,94.6251C86.3543,83.6647 78.229,75.0002 68.2831,75.0002C66.0236,74.9884 63.7843,75.4293 61.6953,76.2973C59.7332,77.1257 57.6272,77.5523 55.5,77.5523C53.3728,77.5523 51.2668,77.1257 49.3047,76.2973C47.2157,75.4293 44.9764,74.9884 42.7169,75.0002C32.771,75.0002 24.6392,83.6647 24.0023,94.6251C23.9918,94.8019 24.0173,94.9789 24.0772,95.1454C24.1371,95.3119 24.2302,95.4642 24.3508,95.593C24.4713,95.7218 24.6167,95.8244 24.7781,95.8944C24.9395,95.9644 25.1133,96.0003 25.289,96.0L85.711,96.0Z"
android:fillColor="#34A853"/>
<path
android:pathData="M56.0,46.0C59.7401,46.0804 63.3003,47.6434 65.9173,50.354C68.5344,53.0645 70.0,56.7068 70.0,60.5C70.0,64.2932 68.5344,67.9355 65.9173,70.646C63.3003,73.3566 59.7401,74.9196 56.0,75.0L56.0,46.0Z"
android:fillColor="#AF735B"/>
<path
android:pathData="M71.0,52.4818L68.6967,57.0L67.0,52.0L71.0,52.4818Z"
android:fillColor="#AF735B"/>
<path
android:pathData="M56.0,75.0C51.9927,74.9196 48.1783,73.3566 45.3743,70.646C42.5703,67.9355 41.0,64.2932 41.0,60.5C41.0,56.7068 42.5703,53.0645 45.3743,50.354C48.1783,47.6434 51.9927,46.0804 56.0,46.0L56.0,75.0Z"
android:fillColor="#2A2952"/>
<path
android:pathData="M69.4697,53.5304L62.4697,46.5304L63.5303,45.4697L70.5303,52.4697L69.4697,53.5304Z"
android:fillColor="#2A2952"/>
<path
android:pathData="M54.4932,60.4471L66.4932,49.4471L67.5068,50.5529L55.5068,61.5529L54.4932,60.4471Z"
android:fillColor="#2A2952"/>
<path
android:pathData="M53.0001,61.0229C52.9971,60.6019 53.0827,60.185 53.2514,59.7993C53.4201,59.4135 53.6682,59.0675 53.9794,58.7838C54.2906,58.5001 54.6581,58.285 55.0579,58.1525C55.4577,58.02 55.881,57.9731 56.3001,58.0147C57.055,58.1109 57.7478,58.482 58.2459,59.057C58.744,59.632 59.0123,60.3704 58.9996,61.1308L58.9996,63.8692C59.0123,64.6296 58.744,65.368 58.2459,65.943C57.7478,66.518 57.055,66.8891 56.3001,66.9853C55.8844,67.0266 55.4645,66.9807 55.0675,66.8506C54.6705,66.7205 54.305,66.5091 53.9944,66.2297C53.6838,65.9504 53.435,65.6094 53.2637,65.2285C53.0925,64.8476 53.0027,64.4351 53.0001,64.0176L53.0001,61.0229Z"
android:fillColor="#AF735B"/>
<path
android:pathData="M34.0,68.0C37.866,68.0 41.0,64.6421 41.0,60.5C41.0,56.3579 37.866,53.0 34.0,53.0C30.134,53.0 27.0,56.3579 27.0,60.5C27.0,64.6421 30.134,68.0 34.0,68.0Z"
android:fillColor="#2A2952"/>
<path
android:pathData="M55.0,16.5C55.0,10.701 59.701,6.0 65.5,6.0L113.5,6.0C119.299,6.0 124.0,10.701 124.0,16.5L124.0,16.5C124.0,22.299 119.299,27.0 113.5,27.0L65.5,27.0C59.701,27.0 55.0,22.299 55.0,16.5L55.0,16.5Z"
android:fillColor="#E7E9EC"/>
<path
android:pathData="M66.3654,100.287L65.0966,99.132C60.5904,95.0457 57.6154,92.3507 57.6154,89.0432C57.6154,86.3482 59.7329,84.2307 62.4279,84.2307C63.9504,84.2307 65.4116,84.9395 66.3654,86.0595C67.3191,84.9395 68.7804,84.2307 70.3029,84.2307C72.9979,84.2307 75.1154,86.3482 75.1154,89.0432C75.1154,92.3507 72.1404,95.0457 67.6341,99.1407L66.3654,100.287Z"
android:fillColor="#FF0000"/>
<path
android:pathData="M62.4279,84.7307C60.009,84.7307 58.1154,86.6244 58.1154,89.0432C58.1154,90.5327 58.7807,91.9233 60.0532,93.479C61.3313,95.0417 63.1693,96.7093 65.4325,98.7616L66.3666,99.612L67.2978,98.7707L67.2989,98.7697L67.3056,98.7637C69.5653,96.7101 71.4006,95.0423 72.6774,93.4802C73.95,91.9234 74.6154,90.5327 74.6154,89.0432C74.6154,86.6244 72.7217,84.7307 70.3029,84.7307C68.9318,84.7307 67.608,85.3714 66.746,86.3836L66.3654,86.8307L65.9847,86.3836C65.1227,85.3714 63.799,84.7307 62.4279,84.7307ZM57.1154,89.0432C57.1154,86.0721 59.4567,83.7307 62.4279,83.7307C63.9099,83.7307 65.3329,84.3396 66.3654,85.3313C67.3978,84.3396 68.8209,83.7307 70.3029,83.7307C73.274,83.7307 75.6154,86.0721 75.6154,89.0432C75.6154,90.8612 74.7932,92.4718 73.4517,94.1131C72.1278,95.7328 70.247,97.4419 68.0299,99.4566L67.9704,99.5107L67.9693,99.5117L66.3641,100.962L64.7607,99.5024L64.7237,99.4688C62.4967,97.4494 60.6076,95.7364 59.2791,94.1121C57.9375,92.4719 57.1154,90.8612 57.1154,89.0432Z"
android:fillColor="#FFFFFF"/>
</vector>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2020 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.
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/zen_mode_settings_senders_image"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</FrameLayout>

View File

@@ -7004,7 +7004,7 @@
<!-- If open app supports TapPay, use that app instead of the default -->
<string name="nfc_payment_favor_open">Except when another payment app is open</string>
<!-- Header for a dialog asking the user which payment app to use -->
<string name="nfc_payment_pay_with">At a Tap &amp; pay terminal, pay with:</string>
<string name="nfc_payment_pay_with">At a contactless terminal, pay with:</string>
<!-- Header for text explaning how to pay at a payment terminal in a store -->
<string name="nfc_how_it_works_title">Paying at the terminal</string>
<!-- Content for text explaning how to pay at a payment terminal in a store -->
@@ -7015,9 +7015,21 @@
<string name="nfc_more_title">More...</string>
<!-- Label for the dialog that is shown when the user is asked to set a
preferred payment application -->
<string name="nfc_payment_set_default_label">Set as your preference?</string>
<string name="nfc_payment_set_default">Always use <xliff:g id="app">%1$s</xliff:g> when you Tap &amp; pay?</string>
<string name="nfc_payment_set_default_instead_of">Always use <xliff:g id="app">%1$s</xliff:g> instead of <xliff:g id="app">%2$s</xliff:g> when you Tap &amp; pay?</string>
<string name="nfc_payment_set_default_label">Set default payment app</string>
<!-- Label for the dialog that is shown when the user is asked to update a
preferred payment application [CHAR LIMIT=50] -->
<string name="nfc_payment_update_default_label">Update default payment app</string>
<string name="nfc_payment_set_default">At a contactless terminal, pay with
<xliff:g id="app">%1$s</xliff:g>
</string>
<string name="nfc_payment_set_default_instead_of">At a contactless terminal, pay with <xliff:g
id="app">%1$s</xliff:g>.\n\nThis replaces <xliff:g id="app">%2$s</xliff:g> as your default
payment app.
</string>
<!-- Label of the Set default button of the Set default payment app dialog [CHAR LIMIT=40] -->
<string name="nfc_payment_btn_text_set_deault">Set default</string>
<!-- Label of the Update button of the Update default payment app dialog [CHAR LIMIT=40] -->
<string name="nfc_payment_btn_text_update">Update</string>
<!-- Restrictions settings --><skip/>
<!-- Restriction settings title [CHAR LIMIT=35] -->
@@ -8525,6 +8537,12 @@
When a user connects select work and personal apps, they can access work and personal data together. [CHAR LIMIT=50] -->
<string name="interact_across_profiles_title">Connected work &amp; personal apps</string>
<!-- Settings subtext. This text is shown when the work and personal apps are connected. [CHAR LIMIT=45] -->
<string name="interact_across_profiles_summary_allowed">Connected</string>
<!-- Settings subtext. This text is shown when the work and personal apps are not connected. [CHAR LIMIT=45] -->
<string name="interact_across_profiles_summary_not_allowed">Not connected</string>
<!-- Settings subtext. This text is shown when a user doesn't have any connected apps. [CHAR LIMIT=NONE] -->
<string name="interact_across_profiles_empty_text">No connected apps</string>
@@ -8591,27 +8609,18 @@
<!-- Banner title. This banner lets a user know that they need to install an app in their
work profile in order to connect it to the corresponding personal app.
The placeholder would be the app name (e.g. Calendar). [CHAR LIMIT=50]-->
<string name="interact_across_profiles_install_work_app_title">Install <xliff:g id="name" example="Calendar">%1$s</xliff:g> in your work profile</string>
<!-- Banner text. This banner lets a user know that they need to install an app in their
work profile in order to connect it to the corresponding personal app.
The placeholder would be the app name (e.g. Calendar). [CHAR LIMIT=NONE]-->
<string name="interact_across_profiles_install_work_app_summary">To connect these apps, install the <xliff:g id="name" example="Calendar">%1$s</xliff:g> app in your work profile</string>
<string name="interact_across_profiles_install_work_app_title">Install work <xliff:g id="name" example="Calendar">%1$s</xliff:g> to connect these apps</string>
<!-- Banner title. This banner lets a user know that they need to install an app in their
personal profile in order to connect it to the corresponding work app.
The placeholder would be the app name (e.g. Calendar). [CHAR LIMIT=50]-->
<string name="interact_across_profiles_install_personal_app_title">Install <xliff:g id="name" example="Calendar">%1$s</xliff:g> in your personal profile</string>
The placeholder would be the app name (e.g. Calendar). [CHAR LIMIT=NONE]-->
<string name="interact_across_profiles_install_personal_app_title">Install personal <xliff:g id="name" example="Calendar">%1$s</xliff:g> to connect these apps</string>
<!-- Banner text. This banner lets a user know that they need to install an app in their
personal profile in order to connect it to the corresponding work app.
work/personal profile in order to connect it to the corresponding personal app.
The placeholder would be the app name (e.g. Calendar). [CHAR LIMIT=NONE]-->
<string name="interact_across_profiles_install_personal_app_summary">To connect these apps, install the <xliff:g id="name" example="Calendar">%1$s</xliff:g> app in your personal profile</string>
<!-- Button text. This button takes a user to the app store so they can download and
install the app they need. [CHAR LIMIT=50]-->
<string name="interact_across_profiles_install_app_action">Get the app</string>
<string name="interact_across_profiles_install_app_summary">Tap to get the app</string>
<!-- Sound & notification > Advanced section: Title for managing Do Not Disturb access option. [CHAR LIMIT=40] -->
<string name="manage_zen_access_title">Do Not Disturb access</string>
@@ -10548,9 +10557,6 @@
<string name="cross_profile_calendar_title">Cross-profile calendar</string>
<!-- [CHAR LIMIT=NONE] Setting description. If the user turns on this setting, they can see their work events on their personal calendar. -->
<string name="cross_profile_calendar_summary">Show work events on your personal calendar</string>
<!-- [CHAR LIMIT=NONE] The preference summary when cross-profile calendar is restricted. -->
<string name="cross_profile_calendar_restricted_summary">Your organization doesn\u2019t allow personal apps to access your work calendar</string>
<!-- Time in hours -->
<plurals name="hours">

View File

@@ -140,11 +140,6 @@
android:ringtoneType="notification"
settings:searchable="false"/>
<SwitchPreference
android:key="notification_people_strip"
android:title="@string/notification_people_strip_title"
settings:controller="com.android.settings.notification.NotificationPeopleStripPreferenceController"/>
<Preference
android:key="gesture_swipe_down_fingerprint_notifications"
android:title="@string/fingerprint_swipe_for_notifications_title"

View File

@@ -15,22 +15,28 @@
~ limitations under the License.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:title="@string/interact_across_profiles_title">
<com.android.settingslib.widget.LayoutPreference
android:key="interact_across_profiles_header"
android:layout="@layout/cross_profiles_settings_entity_header"
android:selectable="false"/>
<com.android.settingslib.widget.LayoutPreference
android:key="interact_across_profiles_header"
android:layout="@layout/cross_profiles_settings_entity_header"
android:selectable="false"/>
<SwitchPreference
android:key="interact_across_profiles_settings_switch" />
<com.android.settings.widget.CardPreference
android:key="install_app_banner"
android:icon="@drawable/ic_download_for_offline"
android:gravity="top"/>
<Preference
android:summary="@string/interact_across_profiles_summary_1"
android:selectable="false" />
<com.android.settingslib.RestrictedSwitchPreference
android:key="interact_across_profiles_settings_switch" />
<Preference
android:summary="@string/interact_across_profiles_summary_2"
android:selectable="false" />
<Preference
android:summary="@string/interact_across_profiles_summary_1"
android:selectable="false" />
<Preference
android:summary="@string/interact_across_profiles_summary_2"
android:selectable="false" />
</PreferenceScreen>

View File

@@ -32,18 +32,10 @@
settings:useAdditionalSummary="true"
settings:controller="com.android.settings.accounts.ContactSearchPreferenceController"/>
<!-- Only one of these preferences will be visible at a time, depending on
CrossProfileCalendarPreferenceController#isCrossProfileCalendarDisallowedByAdmin -->
<SwitchPreference
android:key="cross_profile_calendar"
android:summary="@string/cross_profile_calendar_summary"
android:title="@string/cross_profile_calendar_title"
settings:controller="com.android.settings.accounts.CrossProfileCalendarPreferenceController"/>
<Preference
android:key="cross_profile_calendar_disabled"
android:summary="@string/cross_profile_calendar_restricted_summary"
android:title="@string/cross_profile_calendar_title"
android:enabled="false"
settings:controller="com.android.settings.accounts.CrossProfileCalendarDisabledPreferenceController"/>
</PreferenceScreen>

View File

@@ -25,6 +25,11 @@
android:key="zen_mode_settings_category_calls"
android:title="@string/zen_mode_calls_header"
settings:allowDividerBelow="true">
<!-- Senders image -->
<com.android.settingslib.widget.LayoutPreference
android:key="zen_mode_calls_image"
android:layout="@layout/zen_mode_senders_image" />
</PreferenceCategory>
<!-- Repeat callers -->

View File

@@ -23,6 +23,11 @@
<PreferenceCategory
android:key="zen_mode_settings_category_messages"
android:title="@string/zen_mode_messages_header">
<!-- Senders image -->
<com.android.settingslib.widget.LayoutPreference
android:key="zen_mode_messages_image"
android:layout="@layout/zen_mode_senders_image" />
</PreferenceCategory>
<com.android.settingslib.widget.FooterPreference/>

View File

@@ -1,47 +0,0 @@
/*
* Copyright (C) 2019 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.accounts;
import static com.android.settings.accounts.CrossProfileCalendarPreferenceController.isCrossProfileCalendarDisallowedByAdmin;
import android.content.Context;
import android.os.UserHandle;
import com.android.settings.core.BasePreferenceController;
public class CrossProfileCalendarDisabledPreferenceController extends BasePreferenceController {
private UserHandle mManagedUser;
public void setManagedUser(UserHandle managedUser) {
mManagedUser = managedUser;
}
public CrossProfileCalendarDisabledPreferenceController(Context context,
String preferenceKey) {
super(context, preferenceKey);
}
@Override
public int getAvailabilityStatus() {
if (mManagedUser != null
&& isCrossProfileCalendarDisallowedByAdmin(
mContext, mManagedUser.getIdentifier())) {
return AVAILABLE;
}
return DISABLED_FOR_USER;
}
}

View File

@@ -79,7 +79,6 @@ public class ManagedProfileSettings extends DashboardFragment {
use(WorkModePreferenceController.class).setManagedUser(mManagedUser);
use(ContactSearchPreferenceController.class).setManagedUser(mManagedUser);
use(CrossProfileCalendarPreferenceController.class).setManagedUser(mManagedUser);
use(CrossProfileCalendarDisabledPreferenceController.class).setManagedUser(mManagedUser);
}
@Override

View File

@@ -15,15 +15,25 @@
*/
package com.android.settings.applications.specialaccess.interactacrossprofiles;
import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
import android.Manifest;
import android.annotation.UserIdInt;
import android.app.ActionBar;
import android.app.AppOpsManager;
import android.app.admin.DevicePolicyManager;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.PermissionChecker;
import android.content.pm.CrossProfileApps;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserManager;
@@ -32,13 +42,15 @@ import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.preference.Preference;
import androidx.preference.SwitchPreference;
import com.android.settings.R;
import com.android.settings.applications.AppInfoBase;
import com.android.settings.applications.AppStoreUtil;
import com.android.settings.widget.CardPreference;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedSwitchPreference;
import com.android.settingslib.widget.LayoutPreference;
public class InteractAcrossProfilesDetails extends AppInfoBase
@@ -47,13 +59,21 @@ public class InteractAcrossProfilesDetails extends AppInfoBase
private static final String INTERACT_ACROSS_PROFILES_SETTINGS_SWITCH =
"interact_across_profiles_settings_switch";
private static final String INTERACT_ACROSS_PROFILES_HEADER = "interact_across_profiles_header";
public static final String INSTALL_APP_BANNER_KEY = "install_app_banner";
private Context mContext;
private CrossProfileApps mCrossProfileApps;
private UserManager mUserManager;
private SwitchPreference mSwitchPref;
private RestrictedSwitchPreference mSwitchPref;
private LayoutPreference mHeader;
private CardPreference mInstallBanner;
private PackageManager mPackageManager;
private UserHandle mPersonalProfile;
private UserHandle mWorkProfile;
private boolean mInstalledInPersonal;
private boolean mInstalledInWork;
private String mAppLabel;
private Intent mInstallAppIntent;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -64,19 +84,30 @@ public class InteractAcrossProfilesDetails extends AppInfoBase
mUserManager = mContext.getSystemService(UserManager.class);
mPackageManager = mContext.getPackageManager();
mWorkProfile = InteractAcrossProfilesSettings.getWorkProfile(mUserManager);
mPersonalProfile = mUserManager.getProfileParent(mWorkProfile);
mInstalledInWork = isPackageInstalled(mPackageName, mWorkProfile.getIdentifier());
mInstalledInPersonal = isPackageInstalled(mPackageName, mPersonalProfile.getIdentifier());
mAppLabel = mPackageInfo.applicationInfo.loadLabel(mPackageManager).toString();
mInstallAppIntent = AppStoreUtil.getAppStoreLink(mContext, mPackageName);
addPreferencesFromResource(R.xml.interact_across_profiles_permissions_details);
mSwitchPref = findPreference(INTERACT_ACROSS_PROFILES_SETTINGS_SWITCH);
mSwitchPref.setOnPreferenceClickListener(this);
mHeader = findPreference(INTERACT_ACROSS_PROFILES_HEADER);
mInstallBanner = findPreference(INSTALL_APP_BANNER_KEY);
mInstallBanner.setOnPreferenceClickListener(this);
// refreshUi checks that the user can still configure the appOp, return to the
// previous page if it can't.
if (!refreshUi()) {
setIntentAndFinish(true/* appChanged */);
}
final UserHandle workProfile = getWorkProfile();
final UserHandle personalProfile = mUserManager.getProfileParent(workProfile);
addAppTitleAndIcons(personalProfile, workProfile);
addAppTitleAndIcons(mPersonalProfile, mWorkProfile);
styleActionBar();
}
private void addAppTitleAndIcons(UserHandle personalProfile, UserHandle workProfile) {
@@ -89,70 +120,101 @@ public class InteractAcrossProfilesDetails extends AppInfoBase
final ImageView personalIconView = mHeader.findViewById(R.id.entity_header_icon_personal);
if (personalIconView != null) {
personalIconView.setImageDrawable(IconDrawableFactory.newInstance(mContext)
.getBadgedIcon(mPackageInfo.applicationInfo, personalProfile.getIdentifier()));
Drawable icon = IconDrawableFactory.newInstance(mContext)
.getBadgedIcon(mPackageInfo.applicationInfo, personalProfile.getIdentifier())
.mutate();
if (!mInstalledInPersonal) {
icon.setColorFilter(createSuspendedColorMatrix());
}
personalIconView.setImageDrawable(icon);
}
final ImageView workIconView2 = mHeader.findViewById(R.id.entity_header_icon_work);
if (workIconView2 != null) {
workIconView2.setImageDrawable(IconDrawableFactory.newInstance(mContext)
.getBadgedIcon(mPackageInfo.applicationInfo, workProfile.getIdentifier()));
final ImageView workIconView = mHeader.findViewById(R.id.entity_header_icon_work);
if (workIconView != null) {
Drawable icon = IconDrawableFactory.newInstance(mContext)
.getBadgedIcon(mPackageInfo.applicationInfo, workProfile.getIdentifier())
.mutate();
if (!mInstalledInWork) {
icon.setColorFilter(createSuspendedColorMatrix());
}
workIconView.setImageDrawable(icon);
}
}
@Nullable
private UserHandle getWorkProfile() {
for (UserInfo user : mUserManager.getProfiles(UserHandle.myUserId())) {
if (mUserManager.isManagedProfile(user.id)) {
return user.getUserHandle();
}
private void styleActionBar() {
final ActionBar actionBar = getActivity().getActionBar();
if (actionBar != null) {
actionBar.setElevation(0);
}
return null;
}
private ColorMatrixColorFilter createSuspendedColorMatrix() {
int grayValue = 127;
float scale = 0.5f; // half bright
ColorMatrix tempBrightnessMatrix = new ColorMatrix();
float[] mat = tempBrightnessMatrix.getArray();
mat[0] = scale;
mat[6] = scale;
mat[12] = scale;
mat[4] = grayValue;
mat[9] = grayValue;
mat[14] = grayValue;
ColorMatrix matrix = new ColorMatrix();
matrix.setSaturation(0.0f);
matrix.preConcat(tempBrightnessMatrix);
return new ColorMatrixColorFilter(matrix);
}
@Override
public boolean onPreferenceClick(Preference preference) {
if (preference != mSwitchPref) {
return false;
}
// refreshUi checks that the user can still configure the appOp, return to the
// previous page if it can't.
if (!refreshUi()) {
setIntentAndFinish(true/* appChanged */);
}
if (preference == mSwitchPref) {
handleSwitchPreferenceClick();
return true;
}
if (preference == mInstallBanner) {
handleInstallBannerClick();
return true;
}
return false;
}
private void handleSwitchPreferenceClick() {
if (isInteractAcrossProfilesEnabled()) {
enableInteractAcrossProfiles(false);
refreshUi();
return true;
}
if (!isInteractAcrossProfilesEnabled()) {
} else {
showConsentDialog();
}
return true;
}
private void showConsentDialog() {
final String appLabel = mPackageInfo.applicationInfo.loadLabel(mPackageManager).toString();
final View dialogView = getLayoutInflater().inflate(
R.layout.interact_across_profiles_consent_dialog, null);
final TextView dialogTitle = dialogView.findViewById(
R.id.interact_across_profiles_consent_dialog_title);
dialogTitle.setText(
getString(R.string.interact_across_profiles_consent_dialog_title, appLabel));
getString(R.string.interact_across_profiles_consent_dialog_title, mAppLabel));
final TextView dialogSummary = dialogView.findViewById(
R.id.interact_across_profiles_consent_dialog_summary);
dialogSummary.setText(
getString(R.string.interact_across_profiles_consent_dialog_summary, appLabel));
getString(R.string.interact_across_profiles_consent_dialog_summary, mAppLabel));
final TextView appDataSummary = dialogView.findViewById(R.id.app_data_summary);
appDataSummary.setText(getString(
R.string.interact_across_profiles_consent_dialog_app_data_summary, appLabel));
R.string.interact_across_profiles_consent_dialog_app_data_summary, mAppLabel));
final TextView permissionsSummary = dialogView.findViewById(R.id.permissions_summary);
permissionsSummary.setText(getString(
R.string.interact_across_profiles_consent_dialog_permissions_summary, appLabel));
R.string.interact_across_profiles_consent_dialog_permissions_summary, mAppLabel));
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setView(dialogView)
@@ -171,18 +233,38 @@ public class InteractAcrossProfilesDetails extends AppInfoBase
}
private boolean isInteractAcrossProfilesEnabled() {
return isInteractAcrossProfilesEnabled(
mContext, mPackageName, mPackageInfo.applicationInfo.uid);
return isInteractAcrossProfilesEnabled(mContext, mPackageName);
}
static boolean isInteractAcrossProfilesEnabled(Context context, String packageName, int uid) {
static boolean isInteractAcrossProfilesEnabled(
Context context, String packageName) {
UserManager userManager = context.getSystemService(UserManager.class);
UserHandle workProfile = InteractAcrossProfilesSettings.getWorkProfile(userManager);
UserHandle personalProfile = userManager.getProfileParent(workProfile);
return context.getSystemService(
CrossProfileApps.class).canConfigureInteractAcrossProfiles(packageName)
&& isInteractAcrossProfilesEnabledInProfile(context, packageName, personalProfile)
&& isInteractAcrossProfilesEnabledInProfile(context, packageName, workProfile);
}
private static boolean isInteractAcrossProfilesEnabledInProfile(
Context context, String packageName, UserHandle userHandle) {
final PackageManager packageManager = context.getPackageManager();
final int uid;
try {
uid = packageManager.getApplicationInfoAsUser(
packageName, /* flags= */0, userHandle).uid;
} catch (PackageManager.NameNotFoundException e) {
return false;
}
return PermissionChecker.PERMISSION_GRANTED
== PermissionChecker.checkPermissionForPreflight(
context,
Manifest.permission.INTERACT_ACROSS_PROFILES,
PermissionChecker.PID_UNKNOWN,
uid,
packageName);
context,
Manifest.permission.INTERACT_ACROSS_PROFILES,
PermissionChecker.PID_UNKNOWN,
uid,
packageName);
}
private void enableInteractAcrossProfiles(boolean newState) {
@@ -190,14 +272,28 @@ public class InteractAcrossProfilesDetails extends AppInfoBase
mPackageName, newState ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED);
}
private void handleInstallBannerClick() {
if (mInstallAppIntent == null) {
return;
}
if (!mInstalledInWork) {
mContext.startActivityAsUser(mInstallAppIntent, mWorkProfile);
return;
}
if (!mInstalledInPersonal) {
mContext.startActivityAsUser(mInstallAppIntent, mPersonalProfile);
}
}
/**
* @return the summary for the current state of whether the app associated with the given
* {@code packageName} is allowed to interact across profiles.
*/
public static CharSequence getPreferenceSummary(Context context, String packageName, int uid) {
return context.getString(isInteractAcrossProfilesEnabled(context, packageName, uid)
? R.string.app_permission_summary_allowed
: R.string.app_permission_summary_not_allowed);
public static CharSequence getPreferenceSummary(
Context context, String packageName) {
return context.getString(isInteractAcrossProfilesEnabled(context, packageName)
? R.string.interact_across_profiles_summary_allowed
: R.string.interact_across_profiles_summary_not_allowed);
}
@Override
@@ -205,31 +301,99 @@ public class InteractAcrossProfilesDetails extends AppInfoBase
if (mPackageInfo == null || mPackageInfo.applicationInfo == null) {
return false;
}
if (!mCrossProfileApps.canConfigureInteractAcrossProfiles(mPackageName)) {
if (!mCrossProfileApps.canUserAttemptToConfigureInteractAcrossProfiles(mPackageName)) {
// Invalid app entry. Should not allow changing permission
mSwitchPref.setEnabled(false);
return false;
}
final ImageView horizontalArrowIcon = mHeader.findViewById(R.id.entity_header_swap_horiz);
if (isInteractAcrossProfilesEnabled()) {
mSwitchPref.setChecked(true);
mSwitchPref.setTitle(R.string.interact_across_profiles_switch_enabled);
if (horizontalArrowIcon != null) {
horizontalArrowIcon.setImageDrawable(
mContext.getDrawable(R.drawable.ic_swap_horiz_blue));
}
} else {
mSwitchPref.setChecked(false);
mSwitchPref.setTitle(R.string.interact_across_profiles_switch_disabled);
if (horizontalArrowIcon != null) {
horizontalArrowIcon.setImageDrawable(
mContext.getDrawable(R.drawable.ic_swap_horiz_grey));
}
if (!mCrossProfileApps.canConfigureInteractAcrossProfiles(mPackageName)) {
return refreshUiForNonConfigurableApps();
}
refreshUiForConfigurableApps();
return true;
}
private boolean refreshUiForNonConfigurableApps() {
mSwitchPref.setChecked(false);
mSwitchPref.setTitle(R.string.interact_across_profiles_switch_disabled);
if (!isCrossProfilePackageWhitelisted(mPackageName)) {
mInstallBanner.setVisible(false);
mSwitchPref.setDisabledByAdmin(RestrictedLockUtils.getProfileOrDeviceOwner(
mContext, mWorkProfile));
return true;
}
mSwitchPref.setEnabled(false);
if (!mInstalledInPersonal && !mInstalledInWork) {
return false;
}
if (!mInstalledInPersonal) {
mInstallBanner.setTitle(getString(
R.string.interact_across_profiles_install_personal_app_title,
mAppLabel));
mInstallBanner.setSummary(
R.string.interact_across_profiles_install_app_summary);
mInstallBanner.setVisible(true);
return true;
}
if (!mInstalledInWork) {
mInstallBanner.setTitle(getString(
R.string.interact_across_profiles_install_work_app_title,
mAppLabel));
mInstallBanner.setSummary(
R.string.interact_across_profiles_install_app_summary);
mInstallBanner.setVisible(true);
return true;
}
return false;
}
private boolean isCrossProfilePackageWhitelisted(String packageName) {
return mContext.getSystemService(DevicePolicyManager.class)
.getAllCrossProfilePackages().contains(packageName);
}
private boolean isPackageInstalled(String packageName, @UserIdInt int userId) {
final PackageInfo info;
try {
info = mContext.createContextAsUser(UserHandle.of(userId), /* flags= */0)
.getPackageManager().getPackageInfo(packageName,
MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
} catch (PackageManager.NameNotFoundException e) {
return false;
}
return info != null;
}
private void refreshUiForConfigurableApps() {
mInstallBanner.setVisible(false);
mSwitchPref.setEnabled(true);
if (isInteractAcrossProfilesEnabled()) {
enableSwitchPref();
} else {
disableSwitchPref();
}
}
private void enableSwitchPref() {
mSwitchPref.setChecked(true);
mSwitchPref.setTitle(R.string.interact_across_profiles_switch_enabled);
final ImageView horizontalArrowIcon = mHeader.findViewById(R.id.entity_header_swap_horiz);
if (horizontalArrowIcon != null) {
horizontalArrowIcon.setImageDrawable(
mContext.getDrawable(R.drawable.ic_swap_horiz_blue));
}
}
private void disableSwitchPref() {
mSwitchPref.setChecked(false);
mSwitchPref.setTitle(R.string.interact_across_profiles_switch_disabled);
final ImageView horizontalArrowIcon = mHeader.findViewById(R.id.entity_header_swap_horiz);
if (horizontalArrowIcon != null) {
horizontalArrowIcon.setImageDrawable(
mContext.getDrawable(R.drawable.ic_swap_horiz_grey));
}
}
@Override
protected AlertDialog createDialog(int id, int errorCode) {
return null;

View File

@@ -35,7 +35,7 @@ public class InteractAcrossProfilesDetailsPreferenceController
@Override
public int getAvailabilityStatus() {
return canConfigureInteractAcrossProfiles() ? AVAILABLE : DISABLED_FOR_USER;
return canUserAttemptToConfigureInteractAcrossProfiles() ? AVAILABLE : DISABLED_FOR_USER;
}
@Override
@@ -49,13 +49,12 @@ public class InteractAcrossProfilesDetailsPreferenceController
}
private CharSequence getPreferenceSummary() {
return InteractAcrossProfilesDetails.getPreferenceSummary(mContext, mPackageName,
mParent.getPackageInfo().applicationInfo.uid);
return InteractAcrossProfilesDetails.getPreferenceSummary(mContext, mPackageName);
}
private boolean canConfigureInteractAcrossProfiles() {
private boolean canUserAttemptToConfigureInteractAcrossProfiles() {
return mContext.getSystemService(CrossProfileApps.class)
.canConfigureInteractAcrossProfiles(mPackageName);
.canUserAttemptToConfigureInteractAcrossProfiles(mPackageName);
}
public void setPackageName(String packageName) {

View File

@@ -85,8 +85,8 @@ public class InteractAcrossProfilesSettings extends EmptyTextSettings {
final Preference pref = new AppPreference(prefContext);
pref.setIcon(mIconDrawableFactory.getBadgedIcon(appInfo, user.getIdentifier()));
pref.setTitle(mPackageManager.getUserBadgedLabel(label, user));
pref.setSummary(InteractAcrossProfilesDetails.getPreferenceSummary(prefContext,
packageName, appInfo.uid));
pref.setSummary(InteractAcrossProfilesDetails.getPreferenceSummary(
prefContext, packageName));
pref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
@@ -127,49 +127,78 @@ public class InteractAcrossProfilesSettings extends EmptyTextSettings {
static ArrayList<Pair<ApplicationInfo, UserHandle>> collectConfigurableApps(
PackageManager packageManager, UserManager userManager,
CrossProfileApps crossProfileApps) {
final UserHandle personalProfile = getPersonalProfileForCallingUser(userManager);
final UserHandle workProfile = getWorkProfile(userManager);
if (workProfile == null) {
return new ArrayList<>();
}
final UserHandle personalProfile = userManager.getProfileParent(workProfile);
if (personalProfile == null) {
return new ArrayList<>();
}
final ArrayList<Pair<ApplicationInfo, UserHandle>> apps = new ArrayList<>();
final List<PackageInfo> installedPackages = packageManager.getInstalledPackagesAsUser(
GET_ACTIVITIES, personalProfile.getIdentifier());
for (PackageInfo packageInfo : installedPackages) {
if (crossProfileApps.canConfigureInteractAcrossProfiles(packageInfo.packageName)) {
for (PackageInfo packageInfo : getAllInstalledPackages(
packageManager, personalProfile, workProfile)) {
if (crossProfileApps.canUserAttemptToConfigureInteractAcrossProfiles(
packageInfo.packageName)) {
apps.add(new Pair<>(packageInfo.applicationInfo, personalProfile));
}
}
return apps;
}
private static List<PackageInfo> getAllInstalledPackages(
PackageManager packageManager, UserHandle personalProfile, UserHandle workProfile) {
List<PackageInfo> personalPackages = packageManager.getInstalledPackagesAsUser(
GET_ACTIVITIES, personalProfile.getIdentifier());
List<PackageInfo> workPackages = packageManager.getInstalledPackagesAsUser(
GET_ACTIVITIES, workProfile.getIdentifier());
List<PackageInfo> allPackages = new ArrayList<>(personalPackages);
for (PackageInfo workPackage : workPackages) {
if (allPackages.stream().noneMatch(
p -> workPackage.packageName.equals(p.packageName))) {
allPackages.add(workPackage);
}
}
return allPackages;
}
/**
* @return the number of applications that can interact across profiles.
*/
static int getNumberOfEnabledApps(
Context context, PackageManager packageManager, UserManager userManager,
CrossProfileApps crossProfileApps) {
UserHandle workProfile = getWorkProfile(userManager);
if (workProfile == null) {
return 0;
}
UserHandle personalProfile = userManager.getProfileParent(workProfile);
if (personalProfile == null) {
return 0;
}
final ArrayList<Pair<ApplicationInfo, UserHandle>> apps =
collectConfigurableApps(packageManager, userManager, crossProfileApps);
apps.removeIf(
app -> !InteractAcrossProfilesDetails.isInteractAcrossProfilesEnabled(
context, app.first.packageName, app.first.uid));
context, app.first.packageName)
|| !crossProfileApps.canConfigureInteractAcrossProfiles(
app.first.packageName));
return apps.size();
}
/**
* Returns the personal profile in the profile group of the calling user.
* Returns null if user is not in a profile group.
* Returns the work profile in the profile group of the calling user.
* Returns null if not found.
*/
@Nullable
private static UserHandle getPersonalProfileForCallingUser(UserManager userManager) {
final int callingUser = UserHandle.myUserId();
if (userManager.getProfiles(callingUser).isEmpty()) {
return null;
static UserHandle getWorkProfile(UserManager userManager) {
for (UserInfo user : userManager.getProfiles(UserHandle.myUserId())) {
if (userManager.isManagedProfile(user.id)) {
return user.getUserHandle();
}
}
final UserInfo parentProfile = userManager.getProfileParent(callingUser);
return parentProfile == null
? UserHandle.of(callingUser) : parentProfile.getUserHandle();
return null;
}
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =

View File

@@ -151,7 +151,7 @@ public class MediaDeviceUpdateWorker extends SliceBackgroundWorker
}
MediaDevice getTopDevice() {
return mTopDevice;
return getMediaDeviceById(mTopDevice.getId());
}
boolean addDeviceToPlayMedia(MediaDevice device) {

View File

@@ -27,10 +27,6 @@ import android.util.Log;
import androidx.annotation.VisibleForTesting;
import com.android.ims.ImsManager;
import com.android.settings.network.SubscriptionUtil;
import com.android.settings.network.telephony.MobileNetworkUtils;
/**
* Controller class for querying Wifi calling status
*/
@@ -66,12 +62,6 @@ public class WifiCallingQueryImsState extends ImsQueryController {
return (new ImsQueryWfcUserSetting(subId)).query();
}
@VisibleForTesting
ImsManager getImsManager(int subId) {
return ImsManager.getInstance(mContext,
SubscriptionUtil.getPhoneId(mContext, subId));
}
/**
* Check whether Wifi Calling is a supported feature on this subscription
*
@@ -107,8 +97,15 @@ public class WifiCallingQueryImsState extends ImsQueryController {
if (!SubscriptionManager.isValidSubscriptionId(mSubId)) {
return false;
}
return isWifiCallingProvisioned()
&& MobileNetworkUtils.isImsServiceStateReady(getImsManager(mSubId));
if (!isWifiCallingProvisioned()) {
return false;
}
try {
return isServiceStateReady(mSubId);
} catch (InterruptedException | IllegalArgumentException | ImsException exception) {
Log.w(LOG_TAG, "fail to get WFC service status. subId=" + mSubId, exception);
}
return false;
}
/**

View File

@@ -26,8 +26,8 @@ import static com.android.settings.network.telephony.TelephonyConstants.RadioAcc
import static com.android.settings.network.telephony.TelephonyConstants.RadioAccessFamily.RAF_TD_SCDMA;
import static com.android.settings.network.telephony.TelephonyConstants.RadioAccessFamily.RAF_UNKNOWN;
import static com.android.settings.network.telephony.TelephonyConstants.RadioAccessFamily.WCDMA;
import static com.android.settings.network.telephony.TelephonyConstants.TelephonyManagerConstants.NETWORK_MODE_LTE_GSM_WCDMA;
import static com.android.settings.network.telephony.TelephonyConstants.TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO;
import static com.android.settings.network.telephony.TelephonyConstants.TelephonyManagerConstants.NETWORK_MODE_LTE_GSM_WCDMA;
import static com.android.settings.network.telephony.TelephonyConstants.TelephonyManagerConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO;
import static com.android.settings.network.telephony.TelephonyConstants.TelephonyManagerConstants.NETWORK_MODE_NR_LTE_GSM_WCDMA;
@@ -54,7 +54,6 @@ import android.telephony.euicc.EuiccManager;
import android.telephony.ims.ImsRcsManager;
import android.telephony.ims.ProvisioningManager;
import android.telephony.ims.RcsUceAdapter;
import android.telephony.ims.feature.ImsFeature;
import android.telephony.ims.feature.MmTelFeature;
import android.telephony.ims.stub.ImsRegistrationImplBase;
import android.text.TextUtils;
@@ -63,8 +62,6 @@ import android.view.Gravity;
import androidx.annotation.VisibleForTesting;
import com.android.ims.ImsException;
import com.android.ims.ImsManager;
import com.android.internal.util.ArrayUtils;
import com.android.settings.R;
import com.android.settings.Utils;
@@ -150,7 +147,6 @@ public class MobileNetworkUtils {
final PhoneAccountHandle simCallManager =
context.getSystemService(TelecomManager.class)
.getSimCallManagerForSubscription(subId);
final int phoneId = SubscriptionManager.getSlotIndex(subId);
boolean isWifiCallingEnabled;
if (simCallManager != null) {
@@ -161,9 +157,7 @@ public class MobileNetworkUtils {
} else {
final WifiCallingQueryImsState queryState =
new WifiCallingQueryImsState(context, subId);
final ImsManager imsMgr = ImsManager.getInstance(context, phoneId);
isWifiCallingEnabled = queryState.isWifiCallingProvisioned()
&& isImsServiceStateReady(imsMgr);
isWifiCallingEnabled = queryState.isReadyToWifiCalling();
}
return isWifiCallingEnabled;
@@ -280,21 +274,6 @@ public class MobileNetworkUtils {
return intent;
}
public static boolean isImsServiceStateReady(ImsManager imsMgr) {
boolean isImsServiceStateReady = false;
try {
if (imsMgr != null && imsMgr.getImsServiceState() == ImsFeature.STATE_READY) {
isImsServiceStateReady = true;
}
} catch (ImsException ex) {
Log.e(TAG, "Exception when trying to get ImsServiceStatus: " + ex);
}
Log.d(TAG, "isImsServiceStateReady=" + isImsServiceStateReady);
return isImsServiceStateReady;
}
/**
* Whether to show the entry point to eUICC settings.
*

View File

@@ -111,21 +111,23 @@ public final class PaymentDefaultDialog extends AlertActivity implements
mNewDefault = component;
// Compose dialog; get
final AlertController.AlertParams p = mAlertParams;
p.mTitle = getString(R.string.nfc_payment_set_default_label);
if (defaultPaymentApp == null) {
p.mTitle = getString(R.string.nfc_payment_set_default_label);
String formatString = getString(R.string.nfc_payment_set_default);
String msg = String.format(formatString,
sanitizePaymentAppCaption(requestedPaymentApp.label.toString()));
p.mMessage = msg;
p.mPositiveButtonText = getString(R.string.nfc_payment_btn_text_set_deault);
} else {
p.mTitle = getString(R.string.nfc_payment_update_default_label);
String formatString = getString(R.string.nfc_payment_set_default_instead_of);
String msg = String.format(formatString,
sanitizePaymentAppCaption(requestedPaymentApp.label.toString()),
sanitizePaymentAppCaption(defaultPaymentApp.label.toString()));
p.mMessage = msg;
p.mPositiveButtonText = getString(R.string.nfc_payment_btn_text_update);
}
p.mPositiveButtonText = getString(R.string.yes);
p.mNegativeButtonText = getString(R.string.no);
p.mNegativeButtonText = getString(R.string.cancel);
p.mPositiveButtonListener = this;
p.mNegativeButtonListener = this;
setupAlert();

View File

@@ -1,117 +0,0 @@
/*
* Copyright (C) 2019 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.notification;
import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.core.TogglePreferenceController;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnPause;
import com.android.settingslib.core.lifecycle.events.OnResume;
import com.google.common.annotations.VisibleForTesting;
/** Controls toggle setting for people strip in system ui. */
public class NotificationPeopleStripPreferenceController extends TogglePreferenceController
implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener,
LifecycleObserver, OnResume, OnPause {
@VisibleForTesting
static final int ON = 1;
@VisibleForTesting
static final int OFF = 0;
private final Uri mPeopleStripUri =
Settings.Secure.getUriFor(Settings.Secure.PEOPLE_STRIP);
private Preference mPreference;
private Runnable mUnregisterOnPropertiesChangedListener;
public NotificationPeopleStripPreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mPreference = screen.findPreference("notification_people_strip");
}
@Override
public void onResume() {
if (mPreference == null) {
return;
}
ContentObserver observer = new ContentObserver(new Handler(Looper.getMainLooper())) {
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
updateState(mPreference);
}
};
ContentResolver contentResolver = mContext.getContentResolver();
mUnregisterOnPropertiesChangedListener =
() -> contentResolver.unregisterContentObserver(observer);
contentResolver.registerContentObserver(mPeopleStripUri, false, observer);
}
@Override
public void onPause() {
if (mUnregisterOnPropertiesChangedListener != null) {
mUnregisterOnPropertiesChangedListener.run();
mUnregisterOnPropertiesChangedListener = null;
}
}
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
}
@Override
public boolean isSliceable() {
return false;
}
@Override
public boolean isChecked() {
int value = Settings.Secure.getInt(
mContext.getContentResolver(),
Settings.Secure.PEOPLE_STRIP,
OFF);
return value != OFF;
}
@Override
public boolean setChecked(boolean isChecked) {
return Settings.Secure.putInt(
mContext.getContentResolver(),
Settings.Secure.PEOPLE_STRIP,
isChecked ? ON : OFF);
}
}

View File

@@ -45,6 +45,8 @@ public class ZenModeCallsSettings extends ZenModeSettingsBase {
List<AbstractPreferenceController> controllers = new ArrayList<>();
controllers.add(new ZenModePrioritySendersPreferenceController(context,
"zen_mode_settings_category_calls", lifecycle, false));
controllers.add(new ZenModeSendersImagePreferenceController(context,
"zen_mode_calls_image", lifecycle, false));
controllers.add(new ZenModeRepeatCallersPreferenceController(context, lifecycle,
context.getResources().getInteger(com.android.internal.R.integer
.config_zen_repeat_callers_threshold)));

View File

@@ -44,6 +44,8 @@ public class ZenModeMessagesSettings extends ZenModeSettingsBase {
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
Lifecycle lifecycle) {
List<AbstractPreferenceController> controllers = new ArrayList<>();
controllers.add(new ZenModeSendersImagePreferenceController(context,
"zen_mode_messages_image", lifecycle, true));
controllers.add(new ZenModePrioritySendersPreferenceController(context,
"zen_mode_settings_category_messages", lifecycle, true));
controllers.add(new ZenModeBehaviorFooterPreferenceController(

View File

@@ -58,7 +58,7 @@ public class ZenModePrioritySendersPreferenceController
@VisibleForTesting static final String KEY_NONE = "senders_none";
private static final Intent ALL_CONTACTS_INTENT =
new Intent(Contacts.Intents.UI.LIST_ALL_CONTACTS_ACTION);
new Intent(Contacts.Intents.UI.LIST_DEFAULT);
private static final Intent STARRED_CONTACTS_INTENT =
new Intent(Contacts.Intents.UI.LIST_STARRED_ACTION);
private static final Intent FALLBACK_INTENT = new Intent(Intent.ACTION_MAIN);

View File

@@ -0,0 +1,108 @@
/*
* Copyright (C) 2020 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.notification.zen;
import static android.app.NotificationManager.Policy.PRIORITY_SENDERS_ANY;
import static android.app.NotificationManager.Policy.PRIORITY_SENDERS_CONTACTS;
import static android.app.NotificationManager.Policy.PRIORITY_SENDERS_STARRED;
import android.content.Context;
import android.widget.ImageView;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.widget.LayoutPreference;
/**
* Common preference controller functionality shared by
* ZenModeCallsSettings and ZenModeMessagesSettings.
*
* Changes the image resource based on the selected senders allowed to bypass DND option for
* calls or messages.
*/
public class ZenModeSendersImagePreferenceController
extends AbstractZenModePreferenceController {
private final boolean mIsMessages; // if this is false, then this preference is for calls
private ImageView mImageView;
public ZenModeSendersImagePreferenceController(Context context, String key,
Lifecycle lifecycle, boolean isMessages) {
super(context, key, lifecycle);
mIsMessages = isMessages;
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
LayoutPreference pref = (LayoutPreference) screen.findPreference(KEY);
mImageView = (ImageView) pref.findViewById(R.id.zen_mode_settings_senders_image);
}
@Override
public boolean isAvailable() {
return true;
}
@Override
public String getPreferenceKey() {
return KEY;
}
@Override
public void updateState(Preference preference) {
final int currSetting = getPrioritySenders();
int newImageRes;
CharSequence newContentDescription = "";
if (PRIORITY_SENDERS_ANY == currSetting) {
newImageRes = mIsMessages
? R.drawable.zen_messages_any
: R.drawable.zen_calls_any;
newContentDescription = mContext.getString(R.string.zen_mode_from_anyone);
} else if (PRIORITY_SENDERS_CONTACTS == currSetting) {
newImageRes = mIsMessages
? R.drawable.zen_messages_contacts
: R.drawable.zen_calls_contacts;
newContentDescription = mContext.getString(R.string.zen_mode_from_contacts);
} else if (PRIORITY_SENDERS_STARRED == currSetting) {
newImageRes = mIsMessages
? R.drawable.zen_messages_starred
: R.drawable.zen_calls_starred;
newContentDescription = mContext.getString(R.string.zen_mode_from_starred);
} else {
newImageRes = mIsMessages
? R.drawable.zen_messages_none
: R.drawable.zen_calls_none;
newContentDescription = mContext.getString(R.string.zen_mode_from_none);
}
mImageView.setImageResource(newImageRes);
mImageView.setContentDescription(newContentDescription);
}
private int getPrioritySenders() {
if (mIsMessages) {
return mBackend.getPriorityMessageSenders();
} else {
return mBackend.getPriorityCallSenders();
}
}
}

View File

@@ -214,4 +214,8 @@ public class WifiDialog2 extends AlertDialog implements WifiConfigUiBase2,
public void setCancelButton(CharSequence text) {
setButton(BUTTON_NEGATIVE, text, this);
}
public WifiEntry getWifiEntry() {
return mWifiEntry;
}
}

View File

@@ -647,6 +647,7 @@ public class WifiSettings2 extends RestrictedSettingsFragment
setOffMessage();
setAdditionalSettingsSummaries();
setProgressBarVisible(false);
mClickedConnect = false;
break;
}
}
@@ -739,6 +740,11 @@ public class WifiSettings2 extends RestrictedSettingsFragment
pref.setOnGearClickListener(preference -> {
launchNetworkDetailsFragment(pref);
});
if (mClickedConnect) {
mClickedConnect = false;
scrollToPreference(mConnectedWifiEntryPreferenceCategory);
}
}
} else {
mConnectedWifiEntryPreferenceCategory.removeAll();
@@ -954,18 +960,30 @@ public class WifiSettings2 extends RestrictedSettingsFragment
@Override
public void onForget(WifiDialog2 dialog) {
forget(mDialogWifiEntry);
forget(dialog.getWifiEntry());
}
@Override
public void onSubmit(WifiDialog2 dialog) {
final int dialogMode = mDialog.getController().getMode();
final int dialogMode = dialog.getMode();
final WifiConfiguration config = dialog.getController().getConfig();
final WifiEntry wifiEntry = dialog.getWifiEntry();
if (dialogMode == WifiConfigUiBase2.MODE_MODIFY) {
mWifiManager.save(mDialogWifiEntry.getWifiConfiguration(), mSaveListener);
if (config == null) {
Toast.makeText(getContext(), R.string.wifi_failed_save_message,
Toast.LENGTH_SHORT).show();
} else {
mWifiManager.save(config, mSaveListener);
}
} else if (dialogMode == WifiConfigUiBase2.MODE_CONNECT
|| (dialogMode == WifiConfigUiBase2.MODE_VIEW && mDialogWifiEntry.canConnect())) {
connect(mDialogWifiEntry, false /* editIfNoConfig */, false /* fullScreenEdit*/);
|| (dialogMode == WifiConfigUiBase2.MODE_VIEW && wifiEntry.canConnect())) {
if (config == null) {
connect(wifiEntry, false /* editIfNoConfig */,
false /* fullScreenEdit*/);
} else {
mWifiManager.connect(config, new WifiConnectActionListener());
}
}
}
@@ -981,7 +999,8 @@ public class WifiSettings2 extends RestrictedSettingsFragment
wifiEntry.forget(null /* callback */);
}
private void connect(WifiEntry wifiEntry, boolean editIfNoConfig, boolean fullScreenEdit) {
@VisibleForTesting
void connect(WifiEntry wifiEntry, boolean editIfNoConfig, boolean fullScreenEdit) {
mMetricsFeatureProvider.action(getActivity(), SettingsEnums.ACTION_WIFI_CONNECT,
wifiEntry.isSaved());
@@ -994,7 +1013,7 @@ public class WifiSettings2 extends RestrictedSettingsFragment
private class WifiConnectActionListener implements WifiManager.ActionListener {
@Override
public void onSuccess() {
// Do nothing.
mClickedConnect = true;
}
@Override
@@ -1028,13 +1047,15 @@ public class WifiSettings2 extends RestrictedSettingsFragment
return;
}
if (status == ConnectCallback.CONNECT_STATUS_FAILURE_NO_CONFIG) {
if (status == ConnectCallback.CONNECT_STATUS_SUCCESS) {
mClickedConnect = true;
} else if (status == ConnectCallback.CONNECT_STATUS_FAILURE_NO_CONFIG) {
if (mEditIfNoConfig) {
// Edit an unsaved secure Wi-Fi network.
if (mFullScreenEdit) {
launchConfigNewNetworkFragment(mConnectWifiEntry);
} else {
showDialog(mConnectWifiEntry, WifiConfigUiBase2.MODE_MODIFY);
showDialog(mConnectWifiEntry, WifiConfigUiBase2.MODE_CONNECT);
}
}
} else if (status == CONNECT_STATUS_FAILURE_UNKNOWN) {

View File

@@ -54,9 +54,7 @@ import com.android.settings.SettingsActivity;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.Utils;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.network.SubscriptionUtil;
import com.android.settings.network.ims.WifiCallingQueryImsState;
import com.android.settings.network.telephony.MobileNetworkUtils;
import com.android.settings.widget.SwitchBar;
/**
@@ -100,7 +98,6 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment
private boolean mUseWfcHomeModeForRoaming = false;
private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
private com.android.ims.ImsManager mImsManager;
private ImsMmTelManager mImsMmTelManager;
private ProvisioningManager mProvisioningManager;
private TelephonyManager mTelephonyManager;
@@ -119,8 +116,9 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment
queryImsState(WifiCallingSettingsForSub.this.mSubId).isAllowUserControl();
final boolean isWfcEnabled = mSwitchBar.isChecked()
&& isNonTtyOrTtyOnVolteEnabled;
boolean isCallStateIdle =
mTelephonyManager.getCallState() == TelephonyManager.CALL_STATE_IDLE;
boolean isCallStateIdle = getTelephonyManagerForSub(
WifiCallingSettingsForSub.this.mSubId).getCallState()
== TelephonyManager.CALL_STATE_IDLE;
mSwitchBar.setEnabled(isCallStateIdle
&& isNonTtyOrTtyOnVolteEnabled);
@@ -201,7 +199,8 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment
mSwitchBar.hide();
}
private void showAlert(Intent intent) {
@VisibleForTesting
void showAlert(Intent intent) {
final Context context = getActivity();
final CharSequence title = intent.getCharSequenceExtra(Phone.EXTRA_KEY_ALERT_TITLE);
@@ -247,6 +246,14 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment
return 0;
}
@VisibleForTesting
TelephonyManager getTelephonyManagerForSub(int subId) {
if (mTelephonyManager == null) {
mTelephonyManager = getContext().getSystemService(TelephonyManager.class);
}
return mTelephonyManager.createForSubscriptionId(subId);
}
@VisibleForTesting
WifiCallingQueryImsState queryImsState(int subId) {
return new WifiCallingQueryImsState(getContext(), subId);
@@ -260,12 +267,6 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment
return ProvisioningManager.createForSubscriptionId(mSubId);
}
@VisibleForTesting
com.android.ims.ImsManager getImsManager() {
return com.android.ims.ImsManager.getInstance(getActivity(),
SubscriptionUtil.getPhoneId(getActivity(), mSubId));
}
@VisibleForTesting
ImsMmTelManager getImsMmTelManager() {
if (!SubscriptionManager.isValidSubscriptionId(mSubId)) {
@@ -289,12 +290,9 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment
FRAGMENT_BUNDLE_SUBID, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
}
mImsManager = getImsManager();
mProvisioningManager = getImsProvisioningManager();
mImsMmTelManager = getImsMmTelManager();
mTelephonyManager = getActivity().getSystemService(TelephonyManager.class);
mButtonWfcMode = findPreference(BUTTON_WFC_MODE);
mButtonWfcMode.setOnPreferenceChangeListener(this);
@@ -331,7 +329,7 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment
@VisibleForTesting
boolean isWfcProvisionedOnDevice() {
return MobileNetworkUtils.isWfcProvisionedOnDevice(mSubId);
return queryImsState(mSubId).isWifiCallingProvisioned();
}
private void updateBody() {
@@ -420,7 +418,8 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment
updateBody();
if (queryImsState(mSubId).isWifiCallingSupported()) {
mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
getTelephonyManagerForSub(mSubId).listen(mPhoneStateListener,
PhoneStateListener.LISTEN_CALL_STATE);
mSwitchBar.addOnSwitchChangeListener(this);
@@ -448,7 +447,8 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment
if (mValidListener) {
mValidListener = false;
mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
getTelephonyManagerForSub(mSubId).listen(mPhoneStateListener,
PhoneStateListener.LISTEN_NONE);
mSwitchBar.removeOnSwitchChangeListener(this);
}

View File

@@ -19,10 +19,8 @@ package com.android.settings.wifi.calling;
import android.content.Context;
import android.telephony.SubscriptionManager;
import com.android.ims.ImsManager;
import com.android.settings.SettingsActivity;
import com.android.settings.network.ims.WifiCallingQueryImsState;
import com.android.settings.network.telephony.MobileNetworkUtils;
public class WifiCallingSuggestionActivity extends SettingsActivity {
@@ -30,11 +28,7 @@ public class WifiCallingSuggestionActivity extends SettingsActivity {
final WifiCallingQueryImsState queryState =
new WifiCallingQueryImsState(context,
SubscriptionManager.getDefaultVoiceSubscriptionId());
if (!ImsManager.isWfcEnabledByPlatform(context) ||
!MobileNetworkUtils.isWfcProvisionedOnDevice(
SubscriptionManager.getDefaultVoiceSubscriptionId())) {
return true;
}
return queryState.isEnabledByUser() && queryState.isAllowUserControl();
return (!queryState.isWifiCallingProvisioned())
|| (queryState.isEnabledByUser() && queryState.isAllowUserControl());
}
}

View File

@@ -1,99 +0,0 @@
/*
* Copyright (C) 2018 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.accounts;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
import static com.android.settings.core.BasePreferenceController.DISABLED_FOR_USER;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.robolectric.RuntimeEnvironment.application;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
import android.os.UserHandle;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.Shadows;
import org.robolectric.shadows.ShadowDevicePolicyManager;
import java.util.Collections;
@RunWith(RobolectricTestRunner.class)
public class CrossProfileCalendarDisabledPreferenceControllerTest {
private static final String PREF_KEY = "cross_profile_calendar_disabled";
private static final int MANAGED_USER_ID = 10;
private static final String TEST_PACKAGE_NAME = "com.test";
private static final ComponentName TEST_COMPONENT_NAME = new ComponentName("test", "test");
@Mock
private UserHandle mManagedUser;
private Context mContext;
private CrossProfileCalendarDisabledPreferenceController mController;
private ShadowDevicePolicyManager mDpm;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
mController = new CrossProfileCalendarDisabledPreferenceController(mContext, PREF_KEY);
mController.setManagedUser(mManagedUser);
mDpm = Shadows.shadowOf(application.getSystemService(DevicePolicyManager.class));
when(mManagedUser.getIdentifier()).thenReturn(MANAGED_USER_ID);
doReturn(mContext).when(mContext).createPackageContextAsUser(
any(String.class), anyInt(), any(UserHandle.class));
}
@Test
public void getAvailabilityStatus_noPackageAllowed_shouldBeAvailable() {
mDpm.setProfileOwner(TEST_COMPONENT_NAME);
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
}
@Test
public void getAvailabilityStatus_somePackagesAllowed_shouldBeDisabledForUser() {
mDpm.setProfileOwner(TEST_COMPONENT_NAME);
mDpm.setCrossProfileCalendarPackages(TEST_COMPONENT_NAME,
Collections.singleton(TEST_PACKAGE_NAME));
assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_FOR_USER);
}
@Test
public void getAvailabilityStatus_allPackagesAllowed_shouldBeDisabledForUser() {
mDpm.setProfileOwner(TEST_COMPONENT_NAME);
mDpm.setCrossProfileCalendarPackages(TEST_COMPONENT_NAME, null);
assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_FOR_USER);
}
}

View File

@@ -22,14 +22,18 @@ import static org.robolectric.Shadows.shadowOf;
import android.app.AppOpsManager;
import android.content.Context;
import android.content.pm.CrossProfileApps;
import android.content.pm.PackageManager;
import android.content.pm.PermissionInfo;
import android.os.Process;
import android.content.pm.UserInfo;
import android.os.UserManager;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.google.common.collect.ImmutableList;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
@@ -37,6 +41,9 @@ import org.robolectric.RobolectricTestRunner;
@RunWith(RobolectricTestRunner.class)
public class InteractAcrossProfilesDetailsTest {
private static final int PERSONAL_PROFILE_ID = 0;
private static final int WORK_PROFILE_ID = 10;
private static final int PACKAGE_UID = 0;
private static final String CROSS_PROFILE_PACKAGE_NAME = "crossProfilePackage";
public static final String INTERACT_ACROSS_PROFILES_PERMISSION =
"android.permission.INTERACT_ACROSS_PROFILES";
@@ -44,29 +51,53 @@ public class InteractAcrossProfilesDetailsTest {
private final Context mContext = ApplicationProvider.getApplicationContext();
private final AppOpsManager mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
private final PackageManager mPackageManager = mContext.getPackageManager();
private final InteractAcrossProfilesDetails mFragment = new InteractAcrossProfilesDetails();
private final UserManager mUserManager = mContext.getSystemService(UserManager.class);
private final CrossProfileApps mCrossProfileApps = mContext.getSystemService(
CrossProfileApps.class);
@Test
public void getPreferenceSummary_appOpAllowed_returnsAllowed() {
shadowOf(mUserManager).addUser(
PERSONAL_PROFILE_ID, "personal-profile"/* name */, 0/* flags */);
shadowOf(mUserManager).addProfile(
PERSONAL_PROFILE_ID, WORK_PROFILE_ID,
"work-profile"/* profileName */, UserInfo.FLAG_MANAGED_PROFILE);
shadowOf(mPackageManager).setInstalledPackagesForUserId(
PERSONAL_PROFILE_ID, ImmutableList.of(CROSS_PROFILE_PACKAGE_NAME));
shadowOf(mPackageManager).setInstalledPackagesForUserId(
WORK_PROFILE_ID, ImmutableList.of(CROSS_PROFILE_PACKAGE_NAME));
shadowOf(mCrossProfileApps).addCrossProfilePackage(
CROSS_PROFILE_PACKAGE_NAME);
String appOp = AppOpsManager.permissionToOp(INTERACT_ACROSS_PROFILES_PERMISSION);
shadowOf(mAppOpsManager).setMode(
appOp, Process.myUid(), CROSS_PROFILE_PACKAGE_NAME, AppOpsManager.MODE_ALLOWED);
appOp, PACKAGE_UID, CROSS_PROFILE_PACKAGE_NAME, AppOpsManager.MODE_ALLOWED);
shadowOf(mPackageManager).addPermissionInfo(createCrossProfilesPermissionInfo());
assertThat(mFragment.getPreferenceSummary(
mContext, CROSS_PROFILE_PACKAGE_NAME, Process.myUid()))
assertThat(InteractAcrossProfilesDetails.getPreferenceSummary(
mContext, CROSS_PROFILE_PACKAGE_NAME))
.isEqualTo(mContext.getString(R.string.app_permission_summary_allowed));
}
@Test
public void getPreferenceSummary_appOpNotAllowed_returnsNotAllowed() {
shadowOf(mUserManager).addUser(
PERSONAL_PROFILE_ID, "personal-profile"/* name */, 0/* flags */);
shadowOf(mUserManager).addProfile(
PERSONAL_PROFILE_ID, WORK_PROFILE_ID,
"work-profile"/* profileName */, UserInfo.FLAG_MANAGED_PROFILE);
shadowOf(mPackageManager).setInstalledPackagesForUserId(
PERSONAL_PROFILE_ID, ImmutableList.of(CROSS_PROFILE_PACKAGE_NAME));
shadowOf(mPackageManager).setInstalledPackagesForUserId(
WORK_PROFILE_ID, ImmutableList.of(CROSS_PROFILE_PACKAGE_NAME));
shadowOf(mCrossProfileApps).addCrossProfilePackage(
CROSS_PROFILE_PACKAGE_NAME);
String appOp = AppOpsManager.permissionToOp(INTERACT_ACROSS_PROFILES_PERMISSION);
shadowOf(mAppOpsManager).setMode(
appOp, Process.myUid(), CROSS_PROFILE_PACKAGE_NAME, AppOpsManager.MODE_IGNORED);
appOp, PACKAGE_UID, CROSS_PROFILE_PACKAGE_NAME, AppOpsManager.MODE_IGNORED);
shadowOf(mPackageManager).addPermissionInfo(createCrossProfilesPermissionInfo());
assertThat(mFragment.getPreferenceSummary(
mContext, CROSS_PROFILE_PACKAGE_NAME, Process.myUid()))
assertThat(InteractAcrossProfilesDetails.getPreferenceSummary(
mContext, CROSS_PROFILE_PACKAGE_NAME))
.isEqualTo(mContext.getString(R.string.app_permission_summary_not_allowed));
}

View File

@@ -21,12 +21,15 @@ import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
import android.content.Context;
import android.content.pm.CrossProfileApps;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.core.BasePreferenceController;
import com.google.common.collect.ImmutableList;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
@@ -36,25 +39,34 @@ public class InteractAcrossProfilesPreferenceControllerTest {
private static final String CROSS_PROFILE_PACKAGE_NAME = "crossProfilePackage";
private static final String NOT_CROSS_PROFILE_PACKAGE_NAME = "notCrossProfilePackage";
public static final String INTERACT_ACROSS_PROFILES_PERMISSION =
"android.permission.INTERACT_ACROSS_PROFILES";
private static final int PROFILE_ID = 0;
private final Context mContext = ApplicationProvider.getApplicationContext();
private final CrossProfileApps mCrossProfileApps =
mContext.getSystemService(CrossProfileApps.class);
private final PackageManager mPackageManager = mContext.getPackageManager();
private final InteractAcrossProfilesDetailsPreferenceController mController =
new InteractAcrossProfilesDetailsPreferenceController(mContext, "test_key");
@Test
public void getAvailabilityStatus_crossProfilePackage_returnsAvailable() {
public void getAvailabilityStatus_requestedCrossProfilePermission_returnsAvailable() {
mController.setPackageName(CROSS_PROFILE_PACKAGE_NAME);
shadowOf(mCrossProfileApps).addCrossProfilePackage(CROSS_PROFILE_PACKAGE_NAME);
shadowOf(mPackageManager).setInstalledPackagesForUserId(
PROFILE_ID, ImmutableList.of(CROSS_PROFILE_PACKAGE_NAME));
PackageInfo packageInfo = shadowOf(mPackageManager).getInternalMutablePackageInfo(
CROSS_PROFILE_PACKAGE_NAME);
packageInfo.requestedPermissions = new String[]{
INTERACT_ACROSS_PROFILES_PERMISSION};
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE);
}
@Test
public void getAvailabilityStatus_notCrossProfilePackage_returnsDisabled() {
public void getAvailabilityStatus_notRequestedCrossProfilePermission_returnsDisabled() {
mController.setPackageName(NOT_CROSS_PROFILE_PACKAGE_NAME);
shadowOf(mPackageManager).setInstalledPackagesForUserId(
PROFILE_ID, ImmutableList.of(NOT_CROSS_PROFILE_PACKAGE_NAME));
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.DISABLED_FOR_USER);

View File

@@ -18,14 +18,17 @@ package com.android.settings.applications.specialaccess.interactacrossprofiles;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertTrue;
import static org.robolectric.Shadows.shadowOf;
import android.app.AppOpsManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.CrossProfileApps;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PermissionInfo;
import android.content.pm.UserInfo;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Pair;
@@ -68,49 +71,56 @@ public class InteractAcrossProfilesSettingsTest {
private final CrossProfileApps mCrossProfileApps =
mContext.getSystemService(CrossProfileApps.class);
private final AppOpsManager mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
private final InteractAcrossProfilesSettings mFragment = new InteractAcrossProfilesSettings();
@Test
public void collectConfigurableApps_fromPersonal_returnsPersonalPackages() {
public void collectConfigurableApps_fromPersonal_returnsCombinedPackages() {
shadowOf(mUserManager).addUser(
PERSONAL_PROFILE_ID, "personal-profile"/* name */, 0/* flags */);
shadowOf(mUserManager).addProfile(
PERSONAL_PROFILE_ID, WORK_PROFILE_ID,
"work-profile"/* profileName */, 0/* profileFlags */);
"work-profile"/* profileName */, UserInfo.FLAG_MANAGED_PROFILE);
shadowOf(mPackageManager).setInstalledPackagesForUserId(
PERSONAL_PROFILE_ID, PERSONAL_PROFILE_INSTALLED_PACKAGES);
shadowOf(mPackageManager).setInstalledPackagesForUserId(
WORK_PROFILE_ID, WORK_PROFILE_INSTALLED_PACKAGES);
shadowOf(mCrossProfileApps).addCrossProfilePackage(PERSONAL_CROSS_PROFILE_PACKAGE);
shadowOf(mCrossProfileApps).addCrossProfilePackage(WORK_CROSS_PROFILE_PACKAGE);
installCrossProfilePackage(PERSONAL_PROFILE_ID, PERSONAL_CROSS_PROFILE_PACKAGE);
installCrossProfilePackage(WORK_PROFILE_ID, WORK_CROSS_PROFILE_PACKAGE);
List<Pair<ApplicationInfo, UserHandle>> apps = mFragment.collectConfigurableApps(
mPackageManager, mUserManager, mCrossProfileApps);
List<Pair<ApplicationInfo, UserHandle>> apps =
InteractAcrossProfilesSettings.collectConfigurableApps(
mPackageManager, mUserManager, mCrossProfileApps);
assertThat(apps.size()).isEqualTo(1);
assertThat(apps.get(0).first.packageName).isEqualTo(PERSONAL_CROSS_PROFILE_PACKAGE);
assertThat(apps.size()).isEqualTo(2);
assertTrue(apps.stream().anyMatch(
app -> app.first.packageName.equals(PERSONAL_CROSS_PROFILE_PACKAGE)));
assertTrue(apps.stream().anyMatch(
app -> app.first.packageName.equals(WORK_CROSS_PROFILE_PACKAGE)));
}
@Test
public void collectConfigurableApps_fromWork_returnsPersonalPackages() {
public void collectConfigurableApps_fromWork_returnsCombinedPackages() {
shadowOf(mUserManager).addUser(
PERSONAL_PROFILE_ID, "personal-profile"/* name */, 0/* flags */);
shadowOf(mUserManager).addProfile(
PERSONAL_PROFILE_ID, WORK_PROFILE_ID,
"work-profile"/* profileName */, 0/* profileFlags */);
"work-profile"/* profileName */, UserInfo.FLAG_MANAGED_PROFILE);
ShadowProcess.setUid(WORK_UID);
shadowOf(mPackageManager).setInstalledPackagesForUserId(
PERSONAL_PROFILE_ID, PERSONAL_PROFILE_INSTALLED_PACKAGES);
shadowOf(mPackageManager).setInstalledPackagesForUserId(
WORK_PROFILE_ID, WORK_PROFILE_INSTALLED_PACKAGES);
shadowOf(mCrossProfileApps).addCrossProfilePackage(PERSONAL_CROSS_PROFILE_PACKAGE);
shadowOf(mCrossProfileApps).addCrossProfilePackage(WORK_CROSS_PROFILE_PACKAGE);
installCrossProfilePackage(PERSONAL_PROFILE_ID, PERSONAL_CROSS_PROFILE_PACKAGE);
installCrossProfilePackage(WORK_PROFILE_ID, WORK_CROSS_PROFILE_PACKAGE);
List<Pair<ApplicationInfo, UserHandle>> apps = mFragment.collectConfigurableApps(
mPackageManager, mUserManager, mCrossProfileApps);
List<Pair<ApplicationInfo, UserHandle>> apps =
InteractAcrossProfilesSettings.collectConfigurableApps(
mPackageManager, mUserManager, mCrossProfileApps);
assertThat(apps.size()).isEqualTo(1);
assertThat(apps.get(0).first.packageName).isEqualTo(PERSONAL_CROSS_PROFILE_PACKAGE);
assertThat(apps.size()).isEqualTo(2);
assertTrue(apps.stream().anyMatch(
app -> app.first.packageName.equals(PERSONAL_CROSS_PROFILE_PACKAGE)));
assertTrue(apps.stream().anyMatch(
app -> app.first.packageName.equals(WORK_CROSS_PROFILE_PACKAGE)));
}
@Test
@@ -119,10 +129,11 @@ public class InteractAcrossProfilesSettingsTest {
PERSONAL_PROFILE_ID, "personal-profile"/* name */, 0/* flags */);
shadowOf(mPackageManager).setInstalledPackagesForUserId(
PERSONAL_PROFILE_ID, PERSONAL_PROFILE_INSTALLED_PACKAGES);
shadowOf(mCrossProfileApps).addCrossProfilePackage(PERSONAL_CROSS_PROFILE_PACKAGE);
installCrossProfilePackage(PERSONAL_PROFILE_ID, PERSONAL_CROSS_PROFILE_PACKAGE);
List<Pair<ApplicationInfo, UserHandle>> apps = mFragment.collectConfigurableApps(
mPackageManager, mUserManager, mCrossProfileApps);
List<Pair<ApplicationInfo, UserHandle>> apps =
InteractAcrossProfilesSettings.collectConfigurableApps(
mPackageManager, mUserManager, mCrossProfileApps);
assertThat(apps).isEmpty();
}
@@ -133,11 +144,14 @@ public class InteractAcrossProfilesSettingsTest {
PERSONAL_PROFILE_ID, "personal-profile"/* name */, 0/* flags */);
shadowOf(mUserManager).addProfile(
PERSONAL_PROFILE_ID, WORK_PROFILE_ID,
"work-profile"/* profileName */, 0/* profileFlags */);
"work-profile"/* profileName */, UserInfo.FLAG_MANAGED_PROFILE);
shadowOf(mPackageManager).setInstalledPackagesForUserId(
PERSONAL_PROFILE_ID, PERSONAL_PROFILE_INSTALLED_PACKAGES);
shadowOf(mPackageManager).setInstalledPackagesForUserId(
WORK_PROFILE_ID, WORK_PROFILE_INSTALLED_PACKAGES);
installCrossProfilePackage(PERSONAL_PROFILE_ID, PERSONAL_CROSS_PROFILE_PACKAGE);
installCrossProfilePackage(WORK_PROFILE_ID, WORK_CROSS_PROFILE_PACKAGE);
shadowOf(mCrossProfileApps).addCrossProfilePackage(PERSONAL_CROSS_PROFILE_PACKAGE);
shadowOf(mCrossProfileApps).addCrossProfilePackage(PERSONAL_NON_CROSS_PROFILE_PACKAGE);
String appOp = AppOpsManager.permissionToOp(INTERACT_ACROSS_PROFILES_PERMISSION);
shadowOf(mAppOpsManager).setMode(
appOp, PACKAGE_UID, PERSONAL_CROSS_PROFILE_PACKAGE, AppOpsManager.MODE_ALLOWED);
@@ -145,12 +159,19 @@ public class InteractAcrossProfilesSettingsTest {
appOp, PACKAGE_UID, PERSONAL_NON_CROSS_PROFILE_PACKAGE, AppOpsManager.MODE_IGNORED);
shadowOf(mPackageManager).addPermissionInfo(createCrossProfilesPermissionInfo());
int numOfApps = mFragment.getNumberOfEnabledApps(
int numOfApps = InteractAcrossProfilesSettings.getNumberOfEnabledApps(
mContext, mPackageManager, mUserManager, mCrossProfileApps);
assertThat(numOfApps).isEqualTo(1);
}
private void installCrossProfilePackage(int profileId, String packageName) {
PackageInfo personalPackageInfo = shadowOf(mPackageManager).getInternalMutablePackageInfo(
packageName);
personalPackageInfo.requestedPermissions = new String[]{
INTERACT_ACROSS_PROFILES_PERMISSION};
}
private PermissionInfo createCrossProfilesPermissionInfo() {
PermissionInfo permissionInfo = new PermissionInfo();
permissionInfo.name = INTERACT_ACROSS_PROFILES_PERMISSION;

View File

@@ -19,9 +19,6 @@ package com.android.settings.network.ims;
import android.content.Context;
import android.telephony.ims.ImsException;
import com.android.ims.ImsManager;
/**
* Controller class for mock Wifi calling status
*/
@@ -30,6 +27,7 @@ public class MockWifiCallingQueryImsState extends WifiCallingQueryImsState {
private Boolean mIsTtyOnVolteEnabled;
private Boolean mIsEnabledOnPlatform;
private Boolean mIsProvisionedOnDevice;
private Boolean mIsServiceStateReady;
private Boolean mIsEnabledByUser;
/**
@@ -42,10 +40,6 @@ public class MockWifiCallingQueryImsState extends WifiCallingQueryImsState {
super(context, subId);
}
public ImsManager getImsManager(int subId) {
return super.getImsManager(subId);
}
public void setIsTtyOnVolteEnabled(boolean enabled) {
mIsTtyOnVolteEnabled = enabled;
}
@@ -84,6 +78,19 @@ public class MockWifiCallingQueryImsState extends WifiCallingQueryImsState {
return super.isProvisionedOnDevice(subId);
}
public void setServiceStateReady(boolean isReady) {
mIsServiceStateReady = isReady;
}
@Override
boolean isServiceStateReady(int subId) throws InterruptedException, ImsException,
IllegalArgumentException {
if (mIsServiceStateReady != null) {
return mIsServiceStateReady;
}
return super.isServiceStateReady(subId);
}
public void setIsEnabledByUser(boolean enabled) {
mIsEnabledByUser = enabled;
}

View File

@@ -37,7 +37,6 @@ import android.telephony.ims.ImsMmTelManager;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.ims.ImsManager;
import com.android.internal.R;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.network.ims.MockWifiCallingQueryImsState;
@@ -60,8 +59,6 @@ public class WifiCallingPreferenceControllerTest {
@Mock
private TelephonyManager mTelephonyManager;
@Mock
private ImsManager mImsManager;
@Mock
private ImsMmTelManager mImsMmTelManager;
@Mock
private PreferenceScreen mPreferenceScreen;
@@ -79,9 +76,8 @@ public class WifiCallingPreferenceControllerTest {
mContext = spy(RuntimeEnvironment.application);
mQueryImsState = spy(new MockWifiCallingQueryImsState(mContext, SUB_ID));
doReturn(true).when(mQueryImsState).isEnabledByUser();
doReturn(mImsManager).when(mQueryImsState).getImsManager(anyInt());
mQueryImsState = new MockWifiCallingQueryImsState(mContext, SUB_ID);
mQueryImsState.setIsEnabledByUser(true);
mQueryImsState.setIsProvisionedOnDevice(true);
mPreference = new Preference(mContext);
@@ -109,7 +105,7 @@ public class WifiCallingPreferenceControllerTest {
@Test
public void updateState_noSimCallManager_setCorrectSummary() {
mController.mSimCallManager = null;
doReturn(true).when(mQueryImsState).isEnabledByUser();
mQueryImsState.setIsEnabledByUser(true);
when(mImsMmTelManager.getVoWiFiRoamingModeSetting()).thenReturn(
ImsMmTelManager.WIFI_MODE_WIFI_ONLY);
when(mImsMmTelManager.getVoWiFiModeSetting()).thenReturn(
@@ -149,7 +145,7 @@ public class WifiCallingPreferenceControllerTest {
ImsMmTelManager.WIFI_MODE_WIFI_PREFERRED);
when(mImsMmTelManager.getVoWiFiModeSetting()).thenReturn(
ImsMmTelManager.WIFI_MODE_CELLULAR_PREFERRED);
doReturn(true).when(mQueryImsState).isEnabledByUser();
mQueryImsState.setIsEnabledByUser(true);
when(mTelephonyManager.isNetworkRoaming()).thenReturn(true);
mController.updateState(mPreference);
@@ -166,7 +162,7 @@ public class WifiCallingPreferenceControllerTest {
ImsMmTelManager.WIFI_MODE_WIFI_PREFERRED);
when(mImsMmTelManager.getVoWiFiModeSetting()).thenReturn(
ImsMmTelManager.WIFI_MODE_CELLULAR_PREFERRED);
doReturn(true).when(mQueryImsState).isEnabledByUser();
mQueryImsState.setIsEnabledByUser(true);
when(mTelephonyManager.isNetworkRoaming()).thenReturn(true);
mController.updateState(mPreference);

View File

@@ -1,124 +0,0 @@
/*
* Copyright (C) 2019 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.notification;
import static android.provider.Settings.Secure.PEOPLE_STRIP;
import static com.android.settings.notification.NotificationPeopleStripPreferenceController.OFF;
import static com.android.settings.notification.NotificationPeopleStripPreferenceController.ON;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.provider.Settings;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import androidx.preference.TwoStatePreference;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
@RunWith(RobolectricTestRunner.class)
public class NotificationPeopleStripPreferenceControllerTest {
private static final String KEY_PEOPLE_STRIP = "notification_people_strip";
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Context mContext;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private PreferenceScreen mScreen;
private NotificationPeopleStripPreferenceController mController;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
mController = new NotificationPeopleStripPreferenceController(mContext, KEY_PEOPLE_STRIP);
Preference preference = new Preference(RuntimeEnvironment.application);
preference.setKey(mController.getPreferenceKey());
when(mScreen.findPreference(preference.getKey())).thenReturn(preference);
}
@Test
public void updateState_preferenceSetCheckedWhenSettingIsOn() {
final TwoStatePreference preference = mock(TwoStatePreference.class);
final Context context = RuntimeEnvironment.application;
Settings.Secure.putInt(context.getContentResolver(), PEOPLE_STRIP, ON);
mController = new NotificationPeopleStripPreferenceController(context, KEY_PEOPLE_STRIP);
mController.updateState(preference);
verify(preference).setChecked(true);
}
@Test
public void updateState_preferenceSetUncheckedWhenSettingIsOff() {
final TwoStatePreference preference = mock(TwoStatePreference.class);
final Context context = RuntimeEnvironment.application;
Settings.Secure.putInt(context.getContentResolver(), PEOPLE_STRIP, OFF);
mController = new NotificationPeopleStripPreferenceController(context, KEY_PEOPLE_STRIP);
mController.updateState(preference);
verify(preference).setChecked(false);
}
@Test
public void isChecked_settingIsOff_shouldReturnFalse() {
Settings.Secure.putInt(mContext.getContentResolver(), PEOPLE_STRIP, OFF);
assertThat(mController.isChecked()).isFalse();
}
@Test
public void isChecked_settingIsOn_shouldReturnTrue() {
Settings.Secure.putInt(mContext.getContentResolver(), PEOPLE_STRIP, ON);
assertThat(mController.isChecked()).isTrue();
}
@Test
public void setChecked_setFalse_disablesSetting() {
Settings.Secure.putInt(mContext.getContentResolver(), PEOPLE_STRIP, ON);
mController.setChecked(false);
int updatedValue = Settings.Secure.getInt(mContext.getContentResolver(), PEOPLE_STRIP, -1);
assertThat(updatedValue).isEqualTo(OFF);
}
@Test
public void setChecked_setTrue_enablesSetting() {
Settings.Secure.putInt(mContext.getContentResolver(), PEOPLE_STRIP, OFF);
mController.setChecked(true);
int updatedValue = Settings.Secure.getInt(mContext.getContentResolver(), PEOPLE_STRIP, -1);
assertThat(updatedValue).isEqualTo(ON);
}
}

View File

@@ -15,6 +15,9 @@
*/
package com.android.settings.wifi;
import static com.android.settings.wifi.WifiConfigUiBase2.MODE_CONNECT;
import static com.android.settings.wifi.WifiConfigUiBase2.MODE_MODIFY;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
@@ -34,6 +37,7 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.PowerManager;
@@ -64,6 +68,7 @@ import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowToast;
@RunWith(RobolectricTestRunner.class)
public class WifiSettings2Test {
@@ -303,4 +308,57 @@ public class WifiSettings2Test {
mWifiSettings2.onNumSavedSubscriptionsChanged();
}
@Test
public void onSubmit_modeModifyNoConfig_toastErrorMessage() {
WifiDialog2 dialog = createWifiDialog2(MODE_MODIFY, null /* config */);
mWifiSettings2.onSubmit(dialog);
assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
mContext.getString(R.string.wifi_failed_save_message));
}
@Test
public void onSubmit_modeModifyHasConfig_saveWifiManager() {
final WifiConfiguration config = mock(WifiConfiguration.class);
WifiDialog2 dialog = createWifiDialog2(MODE_MODIFY, config);
mWifiSettings2.onSubmit(dialog);
verify(mWifiManager).save(eq(config), any());
}
@Test
public void onSubmit_modeConnectNoConfig_connectWifiEntry() {
WifiDialog2 dialog = createWifiDialog2(MODE_CONNECT, null /* config */);
final WifiEntry wifiEntry = dialog.getWifiEntry();
mWifiSettings2.onAttach(mContext);
mWifiSettings2.onSubmit(dialog);
verify(mWifiSettings2).connect(wifiEntry, false /* editIfNoConfig */,
false /* fullScreenEdit*/);
}
@Test
public void onSubmit_modeConnectHasConfig_connectWifiManager() {
final WifiConfiguration config = mock(WifiConfiguration.class);
WifiDialog2 dialog = createWifiDialog2(MODE_CONNECT, config);
mWifiSettings2.onSubmit(dialog);
verify(mWifiManager).connect(eq(config), any(WifiManager.ActionListener.class));
}
private WifiDialog2 createWifiDialog2(int mode, WifiConfiguration config) {
final WifiEntry wifiEntry = mock(WifiEntry.class);
when(wifiEntry.canConnect()).thenReturn(true);
final WifiConfigController2 controller = mock(WifiConfigController2.class);
when(controller.getConfig()).thenReturn(config);
final WifiDialog2 wifiDialog2 = spy(WifiDialog2.createModal(mContext, null /* listener */,
wifiEntry, mode));
when(wifiDialog2.getController()).thenReturn(controller);
return wifiDialog2;
}
}

View File

@@ -50,16 +50,15 @@ import android.widget.TextView;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.ims.ImsConfig;
import com.android.ims.ImsManager;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
import com.android.settings.network.ims.MockWifiCallingQueryImsState;
import com.android.settings.network.ims.WifiCallingQueryImsState;
import com.android.settings.testutils.shadow.ShadowFragment;
import com.android.settings.widget.SwitchBar;
import com.android.settings.widget.ToggleSwitch;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -73,6 +72,8 @@ import org.robolectric.util.ReflectionHelpers;
@Config(shadows = ShadowFragment.class)
@RunWith(RobolectricTestRunner.class)
public class WifiCallingSettingsForSubTest {
private static final int SUB_ID = 2;
private static final String BUTTON_WFC_MODE = "wifi_calling_mode";
private static final String BUTTON_WFC_ROAMING_MODE = "wifi_calling_roaming_mode";
private static final String TEST_EMERGENCY_ADDRESS_CARRIER_APP =
@@ -83,9 +84,10 @@ public class WifiCallingSettingsForSubTest {
private TextView mEmptyView;
private final PersistableBundle mBundle = new PersistableBundle();
private MockWifiCallingQueryImsState mQueryImsState;
@Mock private static CarrierConfigManager sCarrierConfigManager;
@Mock private CarrierConfigManager mMockConfigManager;
@Mock private ImsManager mImsManager;
@Mock private ImsMmTelManager mImsMmTelManager;
@Mock private TelephonyManager mTelephonyManager;
@Mock private PreferenceScreen mPreferenceScreen;
@@ -93,7 +95,6 @@ public class WifiCallingSettingsForSubTest {
@Mock private SwitchBar mSwitchBar;
@Mock private ToggleSwitch mToggleSwitch;
@Mock private View mView;
@Mock private ImsConfig mImsConfig;
@Mock private ListWithEntrySummaryPreference mButtonWfcMode;
@Mock private ListWithEntrySummaryPreference mButtonWfcRoamingMode;
@Mock private Preference mUpdateAddress;
@@ -127,12 +128,13 @@ public class WifiCallingSettingsForSubTest {
ReflectionHelpers.setField(mSwitchBar, "mSwitch", mToggleSwitch);
doReturn(mSwitchBar).when(mView).findViewById(R.id.switch_bar);
doReturn(mImsManager).when(mFragment).getImsManager();
mQueryImsState = new MockWifiCallingQueryImsState(mContext, SUB_ID);
doReturn(mImsMmTelManager).when(mFragment).getImsMmTelManager();
doReturn(mImsConfig).when(mImsManager).getConfigInterface();
doReturn(true).when(mFragment).isWfcProvisionedOnDevice();
doReturn(true).when(mImsManager).isWfcEnabledByUser();
doReturn(true).when(mImsManager).isNonTtyOrTtyOnVolteEnabled();
mQueryImsState.setIsProvisionedOnDevice(true);
mQueryImsState.setIsEnabledByPlatform(true);
mQueryImsState.setIsEnabledByUser(true);
mQueryImsState.setIsTtyOnVolteEnabled(true);
doReturn(ImsMmTelManager.WIFI_MODE_WIFI_PREFERRED)
.when(mImsMmTelManager).getVoWiFiModeSetting();
doReturn(ImsMmTelManager.WIFI_MODE_WIFI_PREFERRED)
@@ -178,7 +180,7 @@ public class WifiCallingSettingsForSubTest {
@Test
public void onResume_provisioningDisallowed_shouldFinish() {
// Call onResume while provisioning is disallowed.
doReturn(false).when(mFragment).isWfcProvisionedOnDevice();
mQueryImsState.setIsProvisionedOnDevice(false);
mFragment.onResume();
// Verify that finish() is called
@@ -197,7 +199,6 @@ public class WifiCallingSettingsForSubTest {
}
@Test
@Ignore
public void onResume_useWfcHomeModeConfigFalseAndEditable_shouldShowWfcRoaming() {
// Call onResume to update the WFC roaming preference.
mFragment.onResume();
@@ -351,5 +352,18 @@ public class WifiCallingSettingsForSubTest {
return null;
}
}
@Override
TelephonyManager getTelephonyManagerForSub(int subId) {
return mTelephonyManager;
}
@Override
WifiCallingQueryImsState queryImsState(int subId) {
return mQueryImsState;
}
@Override
void showAlert(Intent intent) {}
}
}

View File

@@ -18,7 +18,6 @@ package com.android.settings.wifi.calling;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
@@ -72,12 +71,10 @@ public class WifiCallingSettingsTest {
mContext = spy(RuntimeEnvironment.application);
mQueryImsState1 = spy(new MockWifiCallingQueryImsState(mContext, SUB_ID1));
mQueryImsState2 = spy(new MockWifiCallingQueryImsState(mContext, SUB_ID2));
doReturn(true).when(mQueryImsState1).isEnabledByUser();
doReturn(true).when(mQueryImsState2).isEnabledByUser();
doReturn(mImsManager).when(mQueryImsState1).getImsManager(anyInt());
doReturn(mImsManager).when(mQueryImsState2).getImsManager(anyInt());
mQueryImsState1 = new MockWifiCallingQueryImsState(mContext, SUB_ID1);
mQueryImsState2 = new MockWifiCallingQueryImsState(mContext, SUB_ID2);
mQueryImsState1.setIsEnabledByUser(true);
mQueryImsState2.setIsEnabledByUser(true);
mQueryImsState1.setIsEnabledByPlatform(true);
mQueryImsState2.setIsEnabledByPlatform(true);
mQueryImsState1.setIsProvisionedOnDevice(true);

View File

@@ -47,7 +47,7 @@ import androidx.slice.widget.SliceLiveData;
import com.android.ims.ImsManager;
import com.android.settings.R;
import com.android.settings.network.ims.WifiCallingQueryImsState;
import com.android.settings.network.ims.MockWifiCallingQueryImsState;
import com.android.settings.slices.CustomSliceRegistry;
import com.android.settings.slices.SettingsSliceProvider;
import com.android.settings.slices.SliceBroadcastReceiver;
@@ -81,7 +81,7 @@ public class WifiCallingSliceHelperTest {
@Mock
private ImsMmTelManager mMockImsMmTelManager;
private WifiCallingQueryImsState mQueryImsState;
private MockWifiCallingQueryImsState mQueryImsState;
private FakeWifiCallingSliceHelper mWfcSliceHelper;
private SettingsSliceProvider mProvider;
@@ -105,9 +105,10 @@ public class WifiCallingSliceHelperTest {
mFeatureFactory = FakeFeatureFactory.setupForTest();
mSlicesFeatureProvider = mFeatureFactory.getSlicesFeatureProvider();
mQueryImsState = spy(new WifiCallingQueryImsState(mContext, SUB_ID));
doReturn(true).when(mQueryImsState).isEnabledByUser();
doReturn(true).when(mQueryImsState).isWifiCallingProvisioned();
mQueryImsState = new MockWifiCallingQueryImsState(mContext, SUB_ID);
mQueryImsState.setIsEnabledByUser(true);
mQueryImsState.setIsEnabledByPlatform(true);
mQueryImsState.setIsProvisionedOnDevice(true);
mWfcSliceHelper = spy(new FakeWifiCallingSliceHelper(mContext));
doReturn(mQueryImsState).when(mWfcSliceHelper).queryImsState(anyInt());
@@ -118,8 +119,8 @@ public class WifiCallingSliceHelperTest {
@Test
public void test_CreateWifiCallingSlice_invalidSubId() {
doReturn(true).when(mQueryImsState).isEnabledByUser();
doReturn(false).when(mQueryImsState).isWifiCallingProvisioned();
mQueryImsState.setIsEnabledByUser(true);
mQueryImsState.setIsProvisionedOnDevice(false);
mWfcSliceHelper.setDefaultVoiceSubId(-1);
final Slice slice = mWfcSliceHelper.createWifiCallingSlice(
@@ -130,7 +131,7 @@ public class WifiCallingSliceHelperTest {
@Test
public void test_CreateWifiCallingSlice_wfcNotSupported() {
doReturn(false).when(mQueryImsState).isWifiCallingProvisioned();
mQueryImsState.setIsProvisionedOnDevice(false);
final Slice slice = mWfcSliceHelper.createWifiCallingSlice(
CustomSliceRegistry.WIFI_CALLING_URI);
@@ -146,9 +147,9 @@ public class WifiCallingSliceHelperTest {
turned off) we need to guide the user to wifi calling settings
activity so the user can perform the activation there.(PrimaryAction)
*/
doReturn(true).when(mQueryImsState).isWifiCallingProvisioned();
doReturn(false).when(mQueryImsState).isEnabledByUser();
when(mMockImsManager.isNonTtyOrTtyOnVolteEnabled()).thenReturn(false);
mQueryImsState.setIsProvisionedOnDevice(true);
mQueryImsState.setIsEnabledByUser(false);
mQueryImsState.setIsTtyOnVolteEnabled(false);
when(mMockCarrierConfigManager.getConfigForSubId(1)).thenReturn(null);
mWfcSliceHelper.setActivationAppIntent(new Intent()); // dummy Intent
@@ -163,9 +164,9 @@ public class WifiCallingSliceHelperTest {
@Test
public void test_CreateWifiCallingSlice_success() {
doReturn(true).when(mQueryImsState).isWifiCallingProvisioned();
doReturn(true).when(mQueryImsState).isEnabledByUser();
when(mMockImsManager.isNonTtyOrTtyOnVolteEnabled()).thenReturn(true);
mQueryImsState.setIsProvisionedOnDevice(true);
mQueryImsState.setIsEnabledByUser(true);
mQueryImsState.setIsTtyOnVolteEnabled(true);
when(mMockCarrierConfigManager.getConfigForSubId(1)).thenReturn(null);
final Slice slice = mWfcSliceHelper.createWifiCallingSlice(
@@ -177,9 +178,9 @@ public class WifiCallingSliceHelperTest {
@Test
public void test_SettingSliceProvider_getsRightSliceWifiCalling() {
doReturn(true).when(mQueryImsState).isWifiCallingProvisioned();
doReturn(true).when(mQueryImsState).isEnabledByUser();
when(mMockImsManager.isNonTtyOrTtyOnVolteEnabled()).thenReturn(true);
mQueryImsState.setIsProvisionedOnDevice(true);
mQueryImsState.setIsEnabledByUser(true);
mQueryImsState.setIsTtyOnVolteEnabled(true);
when(mMockCarrierConfigManager.getConfigForSubId(1)).thenReturn(null);
when(mSlicesFeatureProvider.getNewWifiCallingSliceHelper(mContext))
.thenReturn(mWfcSliceHelper);
@@ -192,9 +193,9 @@ public class WifiCallingSliceHelperTest {
@Test
public void test_SliceBroadcastReceiver_toggleOnWifiCalling() {
doReturn(true).when(mQueryImsState).isWifiCallingProvisioned();
doReturn(false).when(mQueryImsState).isEnabledByUser();
when(mMockImsManager.isNonTtyOrTtyOnVolteEnabled()).thenReturn(true);
mQueryImsState.setIsProvisionedOnDevice(true);
mQueryImsState.setIsEnabledByUser(false);
mQueryImsState.setIsTtyOnVolteEnabled(true);
when(mSlicesFeatureProvider.getNewWifiCallingSliceHelper(mContext))
.thenReturn(mWfcSliceHelper);
mWfcSliceHelper.setActivationAppIntent(null);
@@ -216,9 +217,9 @@ public class WifiCallingSliceHelperTest {
@Test
public void test_CreateWifiCallingPreferenceSlice_prefNotEditable() {
doReturn(true).when(mQueryImsState).isWifiCallingProvisioned();
doReturn(true).when(mQueryImsState).isEnabledByUser();
when(mMockImsManager.isNonTtyOrTtyOnVolteEnabled()).thenReturn(true);
mQueryImsState.setIsProvisionedOnDevice(true);
mQueryImsState.setIsEnabledByUser(true);
mQueryImsState.setIsTtyOnVolteEnabled(true);
mWfcSliceHelper.setIsWifiCallingPrefEditable(false);
final Slice slice = mWfcSliceHelper.createWifiCallingPreferenceSlice(
@@ -230,9 +231,9 @@ public class WifiCallingSliceHelperTest {
@Test
public void test_CreateWifiCallingPreferenceSlice_wfcOff() {
doReturn(true).when(mQueryImsState).isWifiCallingProvisioned();
doReturn(false).when(mQueryImsState).isEnabledByUser();
when(mMockImsManager.isNonTtyOrTtyOnVolteEnabled()).thenReturn(true);
mQueryImsState.setIsProvisionedOnDevice(true);
mQueryImsState.setIsEnabledByUser(false);
mQueryImsState.setIsTtyOnVolteEnabled(true);
mWfcSliceHelper.setIsWifiCallingPrefEditable(true);
final Slice slice = mWfcSliceHelper.createWifiCallingPreferenceSlice(
@@ -246,9 +247,9 @@ public class WifiCallingSliceHelperTest {
@Test
public void test_CreateWifiCallingPreferenceSlice_success() {
doReturn(true).when(mQueryImsState).isWifiCallingProvisioned();
doReturn(true).when(mQueryImsState).isEnabledByUser();
when(mMockImsManager.isNonTtyOrTtyOnVolteEnabled()).thenReturn(true);
mQueryImsState.setIsProvisionedOnDevice(true);
mQueryImsState.setIsEnabledByUser(true);
mQueryImsState.setIsTtyOnVolteEnabled(true);
when(mMockImsMmTelManager.getVoWiFiModeSetting()).thenReturn(
ImsMmTelManager.WIFI_MODE_WIFI_PREFERRED);
mWfcSliceHelper.setIsWifiCallingPrefEditable(true);
@@ -263,9 +264,9 @@ public class WifiCallingSliceHelperTest {
@Test
public void test_SettingsSliceProvider_getWfcPreferenceSlice() {
doReturn(true).when(mQueryImsState).isWifiCallingProvisioned();
doReturn(true).when(mQueryImsState).isEnabledByUser();
when(mMockImsManager.isNonTtyOrTtyOnVolteEnabled()).thenReturn(true);
mQueryImsState.setIsProvisionedOnDevice(true);
mQueryImsState.setIsEnabledByUser(true);
mQueryImsState.setIsTtyOnVolteEnabled(true);
when(mMockImsMmTelManager.getVoWiFiModeSetting()).thenReturn(
ImsMmTelManager.WIFI_MODE_WIFI_PREFERRED);
when(mSlicesFeatureProvider.getNewWifiCallingSliceHelper(mContext))
@@ -281,9 +282,9 @@ public class WifiCallingSliceHelperTest {
}
@Test
public void test_SliceBroadcastReceiver_setWfcPrefCellularPref() {
doReturn(true).when(mQueryImsState).isWifiCallingProvisioned();
doReturn(true).when(mQueryImsState).isEnabledByUser();
when(mMockImsManager.isNonTtyOrTtyOnVolteEnabled()).thenReturn(true);
mQueryImsState.setIsProvisionedOnDevice(true);
mQueryImsState.setIsEnabledByUser(true);
mQueryImsState.setIsTtyOnVolteEnabled(true);
when(mMockImsMmTelManager.getVoWiFiModeSetting()).thenReturn(
ImsMmTelManager.WIFI_MODE_WIFI_PREFERRED);
when(mSlicesFeatureProvider.getNewWifiCallingSliceHelper(mContext))
@@ -447,14 +448,6 @@ public class WifiCallingSliceHelperTest {
mSubId = id;
}
boolean isWfcProvisionedOnDevice(int subId) {
return true;
}
WifiCallingQueryImsState queryImsState(int subId) {
return super.queryImsState(subId);
}
@Override
protected Intent getWifiCallingCarrierActivityIntent(int subId) {
return mActivationAppIntent;

View File

@@ -150,7 +150,6 @@ Cool color temperature;color_temperature
Copyright;copyright
Correction mode;type
Cross-profile calendar;cross_profile_calendar
Cross-profile calendar;cross_profile_calendar_disabled
Current screen saver;current_screensaver
Custom;zen_custom
Custom restrictions;zen_mode_block_settings_page