1#!/usr/bin/env python
2#
3# Copyright (C) 2024 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#      http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17
18import json
19import os
20import time
21import unittest
22
23from vts.testcases.kernel.utils import adb
24from vts.testcases.vndk import utils
25
26class TradeInModeTest(unittest.TestCase):
27
28    def setUp(self):
29        serial_number = os.environ.get("ANDROID_SERIAL")
30        self.assertTrue(serial_number, "$ANDROID_SERIAL is empty.")
31        self.dut = utils.AndroidDevice(serial_number)
32        self.adb = adb.ADB(serial_number)
33        self.buildType = self.dut.Execute("getprop ro.build.type")[0].strip()
34
35    def userBuild(self):
36        if (self.buildType == "user"):
37          return True
38        self.assertTrue(self.buildType in ["userdebug", "eng"])
39        return False
40
41    def reboot(self):
42        self.adb.Execute(["reboot"])
43        try:
44          self.adb.Execute(["wait-for-device"], timeout=900)
45        except self.adb.AdbError as e:
46          self.fail("Exception thrown waiting for device:" + e.msg())
47        for i in range(300):
48          out, err, return_code = self.dut.Execute("getprop sys.boot_completed")
49          if "1" in out:
50            return
51          time.sleep(1)
52        self.fail("Did not boot completely")
53
54    def testEnterTradeInMode(self):
55        if (self.userBuild()):
56          return
57
58        out, err, return_code = self.dut.Execute("su root setprop persist.adb.tradeinmode 1")
59        self.assertEqual(return_code, 0, "Failed to set tradeinmode property")
60        out, err, return_code = self.dut.Execute("su root setprop ctl.restart adbd")
61        self.assertEqual(return_code, 255, "Failed to restart adbd")
62
63        for i in range(30):
64          out, err, return_code = self.dut.Execute("tradeinmode getstatus")
65          if return_code == 0:
66            break
67          time.sleep(1)
68
69        self.assertEquals(return_code, 0, "Failed to getstatus")
70        j = json.loads(out[out.find('{'):])
71        self.assertTrue("serial" in j)
72
73        out, err, return_code = self.dut.Execute("touch /data/local/tmp/tim")
74        self.assertEqual(return_code, 1, "Used shell in TIM foyer")
75
76        # Enter evaluation mode. This can return either 0 (success) or 255 (adb disconnected)
77        # depending on whether the tool returns before adb restarts or not.
78        out, err, return_code = self.dut.Execute("tradeinmode evaluate")
79        self.assertIn(return_code, [0, 255], "Failed to enter evaluation mode")
80
81        for i in range(30):
82          out, err, return_code = self.dut.Execute("touch /data/local/tmp/tim")
83          if return_code == 0:
84            break
85          time.sleep(1)
86        self.assertEqual(return_code, 0, "Failed to use shell")
87        out, err, return_code = self.dut.Execute("ls /data/local/tmp")
88        self.assertEqual(return_code, 0, "Failed to ls tmp dir")
89        self.assertTrue("tim" in out, "Failed to create tim file")
90
91        self.reboot()
92
93        out, err, return_code = self.dut.Execute("su root am start -a com.android.setupwizard.EXIT")
94        self.assertEqual(return_code, 0, "Failed to skip setup wizard")
95        out, err, return_code = self.dut.Execute("ls /data/local/tmp")
96        self.assertEqual(return_code, 0, "Failed to ls tmp dir")
97        self.assertFalse("tim" in out, "Failed to wipe device")
98
99if __name__ == "__main__":
100    # Setting verbosity is required to generate output that the TradeFed test
101    # runner can parse.
102    unittest.main(verbosity=3)
103