19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Rootpackage com.android.server.pm; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageStats; 20a3cdaa5337fa573c4c61770195d6232c2e587090Jason parksimport android.net.LocalSocket; 21cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Rootimport android.net.LocalSocketAddress; 228a9b22056b13477f59df934928c00c58b5871c95Joe Onoratoimport android.util.Slog; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.InputStream; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.OutputStream; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28f69c812f49cb2dea296cd319984e58af026f4c3aJeff Brownpublic final class Installer { 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "Installer"; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3163ebffcb84f4e2fc55d576aed07c4559f66d97a8Joe Onorato private static final boolean LOCAL_DEBUG = false; 32cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root 33cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root InputStream mIn; 34cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root 35cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root OutputStream mOut; 36cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root 37cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root LocalSocket mSocket; 38cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root 39cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root byte buf[] = new byte[1024]; 40cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root 41cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root int buflen = 0; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean connect() { 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mSocket != null) { 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 478a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.i(TAG, "connecting..."); 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSocket = new LocalSocket(); 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 51cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root LocalSocketAddress address = new LocalSocketAddress("installd", 52cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root LocalSocketAddress.Namespace.RESERVED); 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSocket.connect(address); 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIn = mSocket.getInputStream(); 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOut = mSocket.getOutputStream(); 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException ex) { 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project disconnect(); 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 65cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root private void disconnect() { 66cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root Slog.i(TAG, "disconnecting..."); 67cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root try { 68cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root if (mSocket != null) 69cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root mSocket.close(); 70cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } catch (IOException ex) { 71cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 72cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root try { 73cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root if (mIn != null) 74cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root mIn.close(); 75cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } catch (IOException ex) { 76cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 77cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root try { 78cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root if (mOut != null) 79cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root mOut.close(); 80cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } catch (IOException ex) { 81cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 82cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root mSocket = null; 83cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root mIn = null; 84cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root mOut = null; 85cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 86cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root 87cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root private boolean readBytes(byte buffer[], int len) { 88cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root int off = 0, count; 89cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root if (len < 0) 90cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root return false; 91cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root while (off != len) { 92cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root try { 93cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root count = mIn.read(buffer, off, len - off); 94cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root if (count <= 0) { 958a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "read error " + count); 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 98cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root off += count; 99cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } catch (IOException ex) { 100cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root Slog.e(TAG, "read exception"); 101cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root break; 102cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 103cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 104cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root if (LOCAL_DEBUG) { 105cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root Slog.i(TAG, "read " + len + " bytes"); 106cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 107cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root if (off == len) 108cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root return true; 109cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root disconnect(); 110cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root return false; 111cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 112cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root 113cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root private boolean readReply() { 114cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root int len; 115cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root buflen = 0; 116cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root if (!readBytes(buf, 2)) 117cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root return false; 118cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root len = (((int) buf[0]) & 0xff) | ((((int) buf[1]) & 0xff) << 8); 119cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root if ((len < 1) || (len > 1024)) { 120cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root Slog.e(TAG, "invalid reply length (" + len + ")"); 121cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root disconnect(); 122cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root return false; 123cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 124cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root if (!readBytes(buf, len)) 125cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root return false; 126cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root buflen = len; 127cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root return true; 128cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 129cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root 130cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root private boolean writeCommand(String _cmd) { 131cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root byte[] cmd = _cmd.getBytes(); 132cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root int len = cmd.length; 133cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root if ((len < 1) || (len > 1024)) 134cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root return false; 135cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root buf[0] = (byte) (len & 0xff); 136cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root buf[1] = (byte) ((len >> 8) & 0xff); 137cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root try { 138cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root mOut.write(buf, 0, 2); 139cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root mOut.write(cmd, 0, len); 140cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } catch (IOException ex) { 141cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root Slog.e(TAG, "write error"); 142cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root disconnect(); 143cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root return false; 144cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 145cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root return true; 146cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 147cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root 148cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root private synchronized String transaction(String cmd) { 149cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root if (!connect()) { 1508a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "connection failed"); 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "-1"; 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!writeCommand(cmd)) { 155cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root /* 156cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root * If installd died and restarted in the background (unlikely but 157cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root * possible) we'll fail on the next write (this one). Try to 158cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root * reconnect and write the command one more time before giving up. 159cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root */ 1608a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "write command failed? reconnect!"); 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!connect() || !writeCommand(cmd)) { 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "-1"; 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 165cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root if (LOCAL_DEBUG) { 166cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root Slog.i(TAG, "send: '" + cmd + "'"); 167cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 168cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root if (readReply()) { 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String s = new String(buf, 0, buflen); 170cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root if (LOCAL_DEBUG) { 171cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root Slog.i(TAG, "recv: '" + s + "'"); 172cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 173cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root return s; 174cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } else { 175cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root if (LOCAL_DEBUG) { 176cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root Slog.i(TAG, "fail"); 177cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 178cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root return "-1"; 179cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 180cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 181cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root 182cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root private int execute(String cmd) { 183cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root String res = transaction(cmd); 184cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root try { 185cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root return Integer.parseInt(res); 186cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } catch (NumberFormatException ex) { 187cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root return -1; 188cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 189cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19135ab3ad61fcc349380d7e7f2fcf9a0dfbf76ae11Kenny Root public int install(String name, int uid, int gid) { 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project StringBuilder builder = new StringBuilder("install"); 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.append(' '); 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.append(name); 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.append(' '); 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.append(uid); 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.append(' '); 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.append(gid); 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return execute(builder.toString()); 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int dexopt(String apkPath, int uid, boolean isPublic) { 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project StringBuilder builder = new StringBuilder("dexopt"); 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.append(' '); 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.append(apkPath); 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.append(' '); 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.append(uid); 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.append(isPublic ? " 1" : " 0"); 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return execute(builder.toString()); 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int movedex(String srcPath, String dstPath) { 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project StringBuilder builder = new StringBuilder("movedex"); 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.append(' '); 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.append(srcPath); 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.append(' '); 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.append(dstPath); 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return execute(builder.toString()); 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int rmdex(String codePath) { 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project StringBuilder builder = new StringBuilder("rmdex"); 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.append(' '); 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.append(codePath); 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return execute(builder.toString()); 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2280b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani public int remove(String name, int userId) { 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project StringBuilder builder = new StringBuilder("remove"); 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.append(' '); 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.append(name); 2320b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani builder.append(' '); 2330b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani builder.append(userId); 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return execute(builder.toString()); 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23735ab3ad61fcc349380d7e7f2fcf9a0dfbf76ae11Kenny Root public int rename(String oldname, String newname) { 238b858dfda5012a1040927ed62c3bb856c3294d882Dianne Hackborn StringBuilder builder = new StringBuilder("rename"); 239b858dfda5012a1040927ed62c3bb856c3294d882Dianne Hackborn builder.append(' '); 240b858dfda5012a1040927ed62c3bb856c3294d882Dianne Hackborn builder.append(oldname); 241b858dfda5012a1040927ed62c3bb856c3294d882Dianne Hackborn builder.append(' '); 242b858dfda5012a1040927ed62c3bb856c3294d882Dianne Hackborn builder.append(newname); 243b858dfda5012a1040927ed62c3bb856c3294d882Dianne Hackborn return execute(builder.toString()); 244b858dfda5012a1040927ed62c3bb856c3294d882Dianne Hackborn } 245b858dfda5012a1040927ed62c3bb856c3294d882Dianne Hackborn 246383fa18b511c195cc51a96c5504442bfec998e9fDave Burke public int fixUid(String name, int uid, int gid) { 247d0c5f515c05d05c9d24971695337daf9d6ce409cDianne Hackborn StringBuilder builder = new StringBuilder("fixuid"); 248d0c5f515c05d05c9d24971695337daf9d6ce409cDianne Hackborn builder.append(' '); 249d0c5f515c05d05c9d24971695337daf9d6ce409cDianne Hackborn builder.append(name); 250d0c5f515c05d05c9d24971695337daf9d6ce409cDianne Hackborn builder.append(' '); 251d0c5f515c05d05c9d24971695337daf9d6ce409cDianne Hackborn builder.append(uid); 252d0c5f515c05d05c9d24971695337daf9d6ce409cDianne Hackborn builder.append(' '); 253383fa18b511c195cc51a96c5504442bfec998e9fDave Burke builder.append(gid); 254d0c5f515c05d05c9d24971695337daf9d6ce409cDianne Hackborn return execute(builder.toString()); 255d0c5f515c05d05c9d24971695337daf9d6ce409cDianne Hackborn } 256d0c5f515c05d05c9d24971695337daf9d6ce409cDianne Hackborn 25754289b8b4a110cc1ae106d79785cc762a2aebd6eAmith Yamasani public int deleteCacheFiles(String name, int userId) { 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project StringBuilder builder = new StringBuilder("rmcache"); 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.append(' '); 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.append(name); 26154289b8b4a110cc1ae106d79785cc762a2aebd6eAmith Yamasani builder.append(' '); 26254289b8b4a110cc1ae106d79785cc762a2aebd6eAmith Yamasani builder.append(userId); 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return execute(builder.toString()); 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 265cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root 2660b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani public int createUserData(String name, int uid, int userId) { 2670b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani StringBuilder builder = new StringBuilder("mkuserdata"); 2680b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani builder.append(' '); 2690b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani builder.append(name); 2700b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani builder.append(' '); 2710b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani builder.append(uid); 2720b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani builder.append(' '); 2730b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani builder.append(userId); 2740b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani return execute(builder.toString()); 2750b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani } 2760b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani 2770b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani public int removeUserDataDirs(int userId) { 2780b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani StringBuilder builder = new StringBuilder("rmuser"); 2790b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani builder.append(' '); 2800b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani builder.append(userId); 2810b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani return execute(builder.toString()); 2820b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani } 2830b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani 2840b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani public int clearUserData(String name, int userId) { 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project StringBuilder builder = new StringBuilder("rmuserdata"); 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.append(' '); 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.append(name); 2880b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani builder.append(' '); 2890b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani builder.append(userId); 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return execute(builder.toString()); 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 292cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root 293742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani /** 294742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani * Clone all the package data directories from srcUserId to targetUserId. If copyData is true, 295742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani * some of the data is also copied, otherwise just empty directories are created with the 296742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani * correct access rights. 297742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani * @param srcUserId user to copy the data directories from 298742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani * @param targetUserId user to copy the data directories to 299742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani * @param copyData whether the data itself is to be copied. If false, empty directories are 300742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani * created. 301742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani * @return success/error code 302742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani */ 303742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani public int cloneUserData(int srcUserId, int targetUserId, boolean copyData) { 304742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani StringBuilder builder = new StringBuilder("cloneuserdata"); 305742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani builder.append(' '); 306742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani builder.append(srcUserId); 307742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani builder.append(' '); 308742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani builder.append(targetUserId); 309742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani builder.append(' '); 310742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani builder.append(copyData ? '1' : '0'); 311742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani return execute(builder.toString()); 312742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani } 313742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean ping() { 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (execute("ping") < 0) { 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 321cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int freeCache(long freeStorageSize) { 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project StringBuilder builder = new StringBuilder("freecache"); 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.append(' '); 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.append(String.valueOf(freeStorageSize)); 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return execute(builder.toString()); 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3290c3804950236fe170ebf6cc7a5f1e3e305b8f315Dianne Hackborn public int getSizeInfo(String pkgName, int persona, String apkPath, String fwdLockApkPath, 330292f8bc9d1b790ab975a87a842c7fabc908b97e0Dianne Hackborn String asecPath, PackageStats pStats) { 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project StringBuilder builder = new StringBuilder("getsize"); 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.append(' '); 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.append(pkgName); 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.append(' '); 3350c3804950236fe170ebf6cc7a5f1e3e305b8f315Dianne Hackborn builder.append(persona); 3360c3804950236fe170ebf6cc7a5f1e3e305b8f315Dianne Hackborn builder.append(' '); 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.append(apkPath); 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.append(' '); 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.append(fwdLockApkPath != null ? fwdLockApkPath : "!"); 340292f8bc9d1b790ab975a87a842c7fabc908b97e0Dianne Hackborn builder.append(' '); 341292f8bc9d1b790ab975a87a842c7fabc908b97e0Dianne Hackborn builder.append(asecPath != null ? asecPath : "!"); 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String s = transaction(builder.toString()); 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String res[] = s.split(" "); 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 346292f8bc9d1b790ab975a87a842c7fabc908b97e0Dianne Hackborn if ((res == null) || (res.length != 5)) { 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pStats.codeSize = Long.parseLong(res[1]); 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pStats.dataSize = Long.parseLong(res[2]); 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pStats.cacheSize = Long.parseLong(res[3]); 353292f8bc9d1b790ab975a87a842c7fabc908b97e0Dianne Hackborn pStats.externalCodeSize = Long.parseLong(res[4]); 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Integer.parseInt(res[0]); 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (NumberFormatException e) { 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 358cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 359b858dfda5012a1040927ed62c3bb856c3294d882Dianne Hackborn 360b858dfda5012a1040927ed62c3bb856c3294d882Dianne Hackborn public int moveFiles() { 361b858dfda5012a1040927ed62c3bb856c3294d882Dianne Hackborn return execute("movefiles"); 362b858dfda5012a1040927ed62c3bb856c3294d882Dianne Hackborn } 3636a6b007c77e5cab7ee435506a4f65824f52028b6Kenny Root 364ddbe50df2ca70700a46e5849347989b520d1113eKenny Root /** 365ddbe50df2ca70700a46e5849347989b520d1113eKenny Root * Links the native library directory in an application's directory to its 366ddbe50df2ca70700a46e5849347989b520d1113eKenny Root * real location. 367ddbe50df2ca70700a46e5849347989b520d1113eKenny Root * 368ddbe50df2ca70700a46e5849347989b520d1113eKenny Root * @param dataPath data directory where the application is 369ddbe50df2ca70700a46e5849347989b520d1113eKenny Root * @param nativeLibPath target native library path 370ddbe50df2ca70700a46e5849347989b520d1113eKenny Root * @return -1 on error 371ddbe50df2ca70700a46e5849347989b520d1113eKenny Root */ 372a3e90798b7ad3ed62e5b31842c699b2f98bd457bKenny Root public int linkNativeLibraryDirectory(String dataPath, String nativeLibPath, int userId) { 3736a6b007c77e5cab7ee435506a4f65824f52028b6Kenny Root if (dataPath == null) { 3749bbd70a96397bd5f1445ad6c21977fccfb350dfaKenny Root Slog.e(TAG, "linkNativeLibraryDirectory dataPath is null"); 3756a6b007c77e5cab7ee435506a4f65824f52028b6Kenny Root return -1; 3766a6b007c77e5cab7ee435506a4f65824f52028b6Kenny Root } else if (nativeLibPath == null) { 3779bbd70a96397bd5f1445ad6c21977fccfb350dfaKenny Root Slog.e(TAG, "linkNativeLibraryDirectory nativeLibPath is null"); 3786a6b007c77e5cab7ee435506a4f65824f52028b6Kenny Root return -1; 3796a6b007c77e5cab7ee435506a4f65824f52028b6Kenny Root } 3806a6b007c77e5cab7ee435506a4f65824f52028b6Kenny Root 3816a6b007c77e5cab7ee435506a4f65824f52028b6Kenny Root StringBuilder builder = new StringBuilder("linklib "); 3826a6b007c77e5cab7ee435506a4f65824f52028b6Kenny Root builder.append(dataPath); 3836a6b007c77e5cab7ee435506a4f65824f52028b6Kenny Root builder.append(' '); 3846a6b007c77e5cab7ee435506a4f65824f52028b6Kenny Root builder.append(nativeLibPath); 385a3e90798b7ad3ed62e5b31842c699b2f98bd457bKenny Root builder.append(' '); 386a3e90798b7ad3ed62e5b31842c699b2f98bd457bKenny Root builder.append(userId); 3876a6b007c77e5cab7ee435506a4f65824f52028b6Kenny Root 3886a6b007c77e5cab7ee435506a4f65824f52028b6Kenny Root return execute(builder.toString()); 3896a6b007c77e5cab7ee435506a4f65824f52028b6Kenny Root } 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 391