1a89087542f774c585b6a6ec535fc294721710521Andreas Gampe/*
2a89087542f774c585b6a6ec535fc294721710521Andreas Gampe * Copyright (C) 2015 The Android Open Source Project
3a89087542f774c585b6a6ec535fc294721710521Andreas Gampe *
4a89087542f774c585b6a6ec535fc294721710521Andreas Gampe * Licensed under the Apache License, Version 2.0 (the "License");
5a89087542f774c585b6a6ec535fc294721710521Andreas Gampe * you may not use this file except in compliance with the License.
6a89087542f774c585b6a6ec535fc294721710521Andreas Gampe * You may obtain a copy of the License at
7a89087542f774c585b6a6ec535fc294721710521Andreas Gampe *
8a89087542f774c585b6a6ec535fc294721710521Andreas Gampe *      http://www.apache.org/licenses/LICENSE-2.0
9a89087542f774c585b6a6ec535fc294721710521Andreas Gampe *
10a89087542f774c585b6a6ec535fc294721710521Andreas Gampe * Unless required by applicable law or agreed to in writing, software
11a89087542f774c585b6a6ec535fc294721710521Andreas Gampe * distributed under the License is distributed on an "AS IS" BASIS,
12a89087542f774c585b6a6ec535fc294721710521Andreas Gampe * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a89087542f774c585b6a6ec535fc294721710521Andreas Gampe * See the License for the specific language governing permissions and
14a89087542f774c585b6a6ec535fc294721710521Andreas Gampe * limitations under the License.
15a89087542f774c585b6a6ec535fc294721710521Andreas Gampe */
16a89087542f774c585b6a6ec535fc294721710521Andreas Gampe
17a89087542f774c585b6a6ec535fc294721710521Andreas Gampepackage com.android.server.pm;
18a89087542f774c585b6a6ec535fc294721710521Andreas Gampe
19a89087542f774c585b6a6ec535fc294721710521Andreas Gampeimport android.content.pm.IOtaDexopt;
20a89087542f774c585b6a6ec535fc294721710521Andreas Gampeimport android.os.RemoteException;
21a89087542f774c585b6a6ec535fc294721710521Andreas Gampeimport android.os.ShellCommand;
22a89087542f774c585b6a6ec535fc294721710521Andreas Gampe
23a89087542f774c585b6a6ec535fc294721710521Andreas Gampeimport java.io.PrintWriter;
24dbce0ac3da5f3d56cb01bb710605d12614bf83cdAndreas Gampeimport java.util.Locale;
25a89087542f774c585b6a6ec535fc294721710521Andreas Gampe
26a89087542f774c585b6a6ec535fc294721710521Andreas Gampeclass OtaDexoptShellCommand extends ShellCommand {
27a89087542f774c585b6a6ec535fc294721710521Andreas Gampe    final IOtaDexopt mInterface;
28a89087542f774c585b6a6ec535fc294721710521Andreas Gampe
29a89087542f774c585b6a6ec535fc294721710521Andreas Gampe    OtaDexoptShellCommand(OtaDexoptService service) {
30a89087542f774c585b6a6ec535fc294721710521Andreas Gampe        mInterface = service;
31a89087542f774c585b6a6ec535fc294721710521Andreas Gampe    }
32a89087542f774c585b6a6ec535fc294721710521Andreas Gampe
33a89087542f774c585b6a6ec535fc294721710521Andreas Gampe    @Override
34a89087542f774c585b6a6ec535fc294721710521Andreas Gampe    public int onCommand(String cmd) {
35a89087542f774c585b6a6ec535fc294721710521Andreas Gampe        if (cmd == null) {
36a89087542f774c585b6a6ec535fc294721710521Andreas Gampe            return handleDefaultCommands(null);
37a89087542f774c585b6a6ec535fc294721710521Andreas Gampe        }
38a89087542f774c585b6a6ec535fc294721710521Andreas Gampe
39a89087542f774c585b6a6ec535fc294721710521Andreas Gampe        final PrintWriter pw = getOutPrintWriter();
40a89087542f774c585b6a6ec535fc294721710521Andreas Gampe        try {
41a89087542f774c585b6a6ec535fc294721710521Andreas Gampe            switch(cmd) {
42a89087542f774c585b6a6ec535fc294721710521Andreas Gampe                case "prepare":
43a89087542f774c585b6a6ec535fc294721710521Andreas Gampe                    return runOtaPrepare();
44a89087542f774c585b6a6ec535fc294721710521Andreas Gampe                case "cleanup":
45a89087542f774c585b6a6ec535fc294721710521Andreas Gampe                    return runOtaCleanup();
46a89087542f774c585b6a6ec535fc294721710521Andreas Gampe                case "done":
47a89087542f774c585b6a6ec535fc294721710521Andreas Gampe                    return runOtaDone();
48a89087542f774c585b6a6ec535fc294721710521Andreas Gampe                case "step":
49a89087542f774c585b6a6ec535fc294721710521Andreas Gampe                    return runOtaStep();
50cc241a580cb9b753d0dde0cea578feb74ad517e7Andreas Gampe                case "next":
51cc241a580cb9b753d0dde0cea578feb74ad517e7Andreas Gampe                    return runOtaNext();
52bf06232f4d440ced8230662a77ca0e8ece6383caAndreas Gampe                case "progress":
53bf06232f4d440ced8230662a77ca0e8ece6383caAndreas Gampe                    return runOtaProgress();
54a89087542f774c585b6a6ec535fc294721710521Andreas Gampe                default:
55a89087542f774c585b6a6ec535fc294721710521Andreas Gampe                    return handleDefaultCommands(cmd);
56a89087542f774c585b6a6ec535fc294721710521Andreas Gampe            }
57a89087542f774c585b6a6ec535fc294721710521Andreas Gampe        } catch (RemoteException e) {
58a89087542f774c585b6a6ec535fc294721710521Andreas Gampe            pw.println("Remote exception: " + e);
59a89087542f774c585b6a6ec535fc294721710521Andreas Gampe        }
60a89087542f774c585b6a6ec535fc294721710521Andreas Gampe        return -1;
61a89087542f774c585b6a6ec535fc294721710521Andreas Gampe    }
62a89087542f774c585b6a6ec535fc294721710521Andreas Gampe
63a89087542f774c585b6a6ec535fc294721710521Andreas Gampe    private int runOtaPrepare() throws RemoteException {
64a89087542f774c585b6a6ec535fc294721710521Andreas Gampe        mInterface.prepare();
65a89087542f774c585b6a6ec535fc294721710521Andreas Gampe        getOutPrintWriter().println("Success");
66a89087542f774c585b6a6ec535fc294721710521Andreas Gampe        return 0;
67a89087542f774c585b6a6ec535fc294721710521Andreas Gampe    }
68a89087542f774c585b6a6ec535fc294721710521Andreas Gampe
69a89087542f774c585b6a6ec535fc294721710521Andreas Gampe    private int runOtaCleanup() throws RemoteException {
70a89087542f774c585b6a6ec535fc294721710521Andreas Gampe        mInterface.cleanup();
71a89087542f774c585b6a6ec535fc294721710521Andreas Gampe        return 0;
72a89087542f774c585b6a6ec535fc294721710521Andreas Gampe    }
73a89087542f774c585b6a6ec535fc294721710521Andreas Gampe
74a89087542f774c585b6a6ec535fc294721710521Andreas Gampe    private int runOtaDone() throws RemoteException {
75a89087542f774c585b6a6ec535fc294721710521Andreas Gampe        final PrintWriter pw = getOutPrintWriter();
76a89087542f774c585b6a6ec535fc294721710521Andreas Gampe        if (mInterface.isDone()) {
77a89087542f774c585b6a6ec535fc294721710521Andreas Gampe            pw.println("OTA complete.");
78a89087542f774c585b6a6ec535fc294721710521Andreas Gampe        } else {
79a89087542f774c585b6a6ec535fc294721710521Andreas Gampe            pw.println("OTA incomplete.");
80a89087542f774c585b6a6ec535fc294721710521Andreas Gampe        }
81a89087542f774c585b6a6ec535fc294721710521Andreas Gampe        return 0;
82a89087542f774c585b6a6ec535fc294721710521Andreas Gampe    }
83a89087542f774c585b6a6ec535fc294721710521Andreas Gampe
84a89087542f774c585b6a6ec535fc294721710521Andreas Gampe    private int runOtaStep() throws RemoteException {
85a89087542f774c585b6a6ec535fc294721710521Andreas Gampe        mInterface.dexoptNextPackage();
86a89087542f774c585b6a6ec535fc294721710521Andreas Gampe        return 0;
87a89087542f774c585b6a6ec535fc294721710521Andreas Gampe    }
88a89087542f774c585b6a6ec535fc294721710521Andreas Gampe
89cc241a580cb9b753d0dde0cea578feb74ad517e7Andreas Gampe    private int runOtaNext() throws RemoteException {
90cc241a580cb9b753d0dde0cea578feb74ad517e7Andreas Gampe        getOutPrintWriter().println(mInterface.nextDexoptCommand());
91cc241a580cb9b753d0dde0cea578feb74ad517e7Andreas Gampe        return 0;
92cc241a580cb9b753d0dde0cea578feb74ad517e7Andreas Gampe    }
93cc241a580cb9b753d0dde0cea578feb74ad517e7Andreas Gampe
94bf06232f4d440ced8230662a77ca0e8ece6383caAndreas Gampe    private int runOtaProgress() throws RemoteException {
95bf06232f4d440ced8230662a77ca0e8ece6383caAndreas Gampe        final float progress = mInterface.getProgress();
96bf06232f4d440ced8230662a77ca0e8ece6383caAndreas Gampe        final PrintWriter pw = getOutPrintWriter();
97dbce0ac3da5f3d56cb01bb710605d12614bf83cdAndreas Gampe        // Note: The float output is parsed by update_engine. It does needs to be non-localized,
98dbce0ac3da5f3d56cb01bb710605d12614bf83cdAndreas Gampe        //       as it's always expected to be "0.xy," never "0,xy" or similar. So use the ROOT
99dbce0ac3da5f3d56cb01bb710605d12614bf83cdAndreas Gampe        //       Locale for formatting. (b/37760573)
100dbce0ac3da5f3d56cb01bb710605d12614bf83cdAndreas Gampe        pw.format(Locale.ROOT, "%.2f", progress);
101bf06232f4d440ced8230662a77ca0e8ece6383caAndreas Gampe        return 0;
102bf06232f4d440ced8230662a77ca0e8ece6383caAndreas Gampe    }
103bf06232f4d440ced8230662a77ca0e8ece6383caAndreas Gampe
104a89087542f774c585b6a6ec535fc294721710521Andreas Gampe    @Override
105a89087542f774c585b6a6ec535fc294721710521Andreas Gampe    public void onHelp() {
106a89087542f774c585b6a6ec535fc294721710521Andreas Gampe        final PrintWriter pw = getOutPrintWriter();
107a89087542f774c585b6a6ec535fc294721710521Andreas Gampe        pw.println("OTA Dexopt (ota) commands:");
108a89087542f774c585b6a6ec535fc294721710521Andreas Gampe        pw.println("  help");
109a89087542f774c585b6a6ec535fc294721710521Andreas Gampe        pw.println("    Print this help text.");
110a89087542f774c585b6a6ec535fc294721710521Andreas Gampe        pw.println("");
111a89087542f774c585b6a6ec535fc294721710521Andreas Gampe        pw.println("  prepare");
112a89087542f774c585b6a6ec535fc294721710521Andreas Gampe        pw.println("    Prepare an OTA dexopt pass, collecting all packages.");
113a89087542f774c585b6a6ec535fc294721710521Andreas Gampe        pw.println("  done");
114a89087542f774c585b6a6ec535fc294721710521Andreas Gampe        pw.println("    Replies whether the OTA is complete or not.");
115a89087542f774c585b6a6ec535fc294721710521Andreas Gampe        pw.println("  step");
116a89087542f774c585b6a6ec535fc294721710521Andreas Gampe        pw.println("    OTA dexopt the next package.");
117cc241a580cb9b753d0dde0cea578feb74ad517e7Andreas Gampe        pw.println("  next");
118cc241a580cb9b753d0dde0cea578feb74ad517e7Andreas Gampe        pw.println("    Get parameters for OTA dexopt of the next package.");
119a89087542f774c585b6a6ec535fc294721710521Andreas Gampe        pw.println("  cleanup");
120a89087542f774c585b6a6ec535fc294721710521Andreas Gampe        pw.println("    Clean up internal states. Ends an OTA session.");
121a89087542f774c585b6a6ec535fc294721710521Andreas Gampe    }
122a89087542f774c585b6a6ec535fc294721710521Andreas Gampe}
123