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