Merge changes Ia7add63e,Ic7571dae
* changes: Split dump and annotate users of mPackages lock Split PackageManagerService into subclasses
This commit is contained in:
@@ -56,7 +56,7 @@ import android.util.Slog;
|
||||
* settings parameter with a default value of 2MB), the free memory is
|
||||
* logged to the event log.
|
||||
*/
|
||||
class DeviceStorageMonitorService extends Binder {
|
||||
public class DeviceStorageMonitorService extends Binder {
|
||||
private static final String TAG = "DeviceStorageMonitorService";
|
||||
private static final boolean DEBUG = false;
|
||||
private static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV;
|
||||
@@ -99,7 +99,7 @@ class DeviceStorageMonitorService extends Binder {
|
||||
/**
|
||||
* This string is used for ServiceManager access to this class.
|
||||
*/
|
||||
static final String SERVICE = "devicestoragemonitor";
|
||||
public static final String SERVICE = "devicestoragemonitor";
|
||||
|
||||
/**
|
||||
* Handler that checks the amount of disk space on the device and sends a
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.server;
|
||||
|
||||
import com.android.internal.app.IMediaContainerService;
|
||||
import com.android.server.am.ActivityManagerService;
|
||||
import com.android.server.pm.PackageManagerService;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.BroadcastReceiver;
|
||||
@@ -86,6 +87,9 @@ class MountService extends IMountService.Stub implements INativeDaemonConnectorC
|
||||
|
||||
private static final String VOLD_TAG = "VoldConnector";
|
||||
|
||||
/** Maximum number of ASEC containers allowed to be mounted. */
|
||||
private static final int MAX_CONTAINERS = 250;
|
||||
|
||||
/*
|
||||
* Internal vold volume state constants
|
||||
*/
|
||||
@@ -483,7 +487,6 @@ class MountService extends IMountService.Stub implements INativeDaemonConnectorC
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private final class MountServiceBinderListener implements IBinder.DeathRecipient {
|
||||
final IMountServiceListener mListener;
|
||||
|
||||
@@ -1087,8 +1090,7 @@ class MountService extends IMountService.Stub implements INativeDaemonConnectorC
|
||||
* amount of containers we'd ever expect to have. This keeps an
|
||||
* "asec list" from blocking a thread repeatedly.
|
||||
*/
|
||||
mConnector = new NativeDaemonConnector(this, "vold",
|
||||
PackageManagerService.MAX_CONTAINERS * 2, VOLD_TAG);
|
||||
mConnector = new NativeDaemonConnector(this, "vold", MAX_CONTAINERS * 2, VOLD_TAG);
|
||||
mReady = false;
|
||||
Thread thread = new Thread(mConnector, VOLD_TAG);
|
||||
thread.start();
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.server;
|
||||
|
||||
import com.android.server.am.ActivityManagerService;
|
||||
import com.android.server.pm.PackageManagerService;
|
||||
import com.android.server.usb.UsbService;
|
||||
import com.android.server.wm.WindowManagerService;
|
||||
import com.android.internal.app.ShutdownThread;
|
||||
|
||||
59
services/java/com/android/server/pm/BasePermission.java
Normal file
59
services/java/com/android/server/pm/BasePermission.java
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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.server.pm;
|
||||
|
||||
import android.content.pm.PackageParser;
|
||||
import android.content.pm.PermissionInfo;
|
||||
|
||||
final class BasePermission {
|
||||
final static int TYPE_NORMAL = 0;
|
||||
|
||||
final static int TYPE_BUILTIN = 1;
|
||||
|
||||
final static int TYPE_DYNAMIC = 2;
|
||||
|
||||
final String name;
|
||||
|
||||
String sourcePackage;
|
||||
|
||||
PackageSettingBase packageSetting;
|
||||
|
||||
final int type;
|
||||
|
||||
int protectionLevel;
|
||||
|
||||
PackageParser.Permission perm;
|
||||
|
||||
PermissionInfo pendingInfo;
|
||||
|
||||
int uid;
|
||||
|
||||
int[] gids;
|
||||
|
||||
BasePermission(String _name, String _sourcePackage, int _type) {
|
||||
name = _name;
|
||||
sourcePackage = _sourcePackage;
|
||||
type = _type;
|
||||
// Default to most conservative protection level.
|
||||
protectionLevel = PermissionInfo.PROTECTION_SIGNATURE;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "BasePermission{" + Integer.toHexString(System.identityHashCode(this)) + " " + name
|
||||
+ "}";
|
||||
}
|
||||
}
|
||||
50
services/java/com/android/server/pm/GrantedPermissions.java
Normal file
50
services/java/com/android/server/pm/GrantedPermissions.java
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.server.pm;
|
||||
|
||||
import android.content.pm.ApplicationInfo;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
class GrantedPermissions {
|
||||
int pkgFlags;
|
||||
|
||||
HashSet<String> grantedPermissions = new HashSet<String>();
|
||||
|
||||
int[] gids;
|
||||
|
||||
GrantedPermissions(int pkgFlags) {
|
||||
setFlags(pkgFlags);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
GrantedPermissions(GrantedPermissions base) {
|
||||
pkgFlags = base.pkgFlags;
|
||||
grantedPermissions = (HashSet<String>) base.grantedPermissions.clone();
|
||||
|
||||
if (base.gids != null) {
|
||||
gids = base.gids.clone();
|
||||
}
|
||||
}
|
||||
|
||||
void setFlags(int pkgFlags) {
|
||||
this.pkgFlags = pkgFlags
|
||||
& (ApplicationInfo.FLAG_SYSTEM
|
||||
| ApplicationInfo.FLAG_FORWARD_LOCK
|
||||
| ApplicationInfo.FLAG_EXTERNAL_STORAGE);
|
||||
}
|
||||
}
|
||||
@@ -14,28 +14,31 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server;
|
||||
package com.android.server.pm;
|
||||
|
||||
import android.content.pm.PackageStats;
|
||||
import android.net.LocalSocketAddress;
|
||||
import android.net.LocalSocket;
|
||||
import android.util.Config;
|
||||
import android.net.LocalSocketAddress;
|
||||
import android.util.Slog;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.Socket;
|
||||
|
||||
|
||||
class Installer {
|
||||
private static final String TAG = "Installer";
|
||||
InputStream mIn;
|
||||
OutputStream mOut;
|
||||
LocalSocket mSocket;
|
||||
|
||||
byte buf[] = new byte[1024];
|
||||
int buflen = 0;
|
||||
private static final boolean LOCAL_DEBUG = true;
|
||||
|
||||
InputStream mIn;
|
||||
|
||||
OutputStream mOut;
|
||||
|
||||
LocalSocket mSocket;
|
||||
|
||||
byte buf[] = new byte[1024];
|
||||
|
||||
int buflen = 0;
|
||||
|
||||
private boolean connect() {
|
||||
if (mSocket != null) {
|
||||
@@ -45,8 +48,8 @@ class Installer {
|
||||
try {
|
||||
mSocket = new LocalSocket();
|
||||
|
||||
LocalSocketAddress address = new LocalSocketAddress(
|
||||
"installd", LocalSocketAddress.Namespace.RESERVED);
|
||||
LocalSocketAddress address = new LocalSocketAddress("installd",
|
||||
LocalSocketAddress.Namespace.RESERVED);
|
||||
|
||||
mSocket.connect(address);
|
||||
|
||||
@@ -59,112 +62,131 @@ class Installer {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void disconnect() {
|
||||
Slog.i(TAG,"disconnecting...");
|
||||
try {
|
||||
if (mSocket != null) mSocket.close();
|
||||
} catch (IOException ex) { }
|
||||
try {
|
||||
if (mIn != null) mIn.close();
|
||||
} catch (IOException ex) { }
|
||||
try {
|
||||
if (mOut != null) mOut.close();
|
||||
} catch (IOException ex) { }
|
||||
mSocket = null;
|
||||
mIn = null;
|
||||
mOut = null;
|
||||
}
|
||||
private void disconnect() {
|
||||
Slog.i(TAG, "disconnecting...");
|
||||
try {
|
||||
if (mSocket != null)
|
||||
mSocket.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
try {
|
||||
if (mIn != null)
|
||||
mIn.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
try {
|
||||
if (mOut != null)
|
||||
mOut.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
mSocket = null;
|
||||
mIn = null;
|
||||
mOut = null;
|
||||
}
|
||||
|
||||
private boolean readBytes(byte buffer[], int len) {
|
||||
int off = 0, count;
|
||||
if (len < 0) return false;
|
||||
while (off != len) {
|
||||
try {
|
||||
count = mIn.read(buffer, off, len - off);
|
||||
if (count <= 0) {
|
||||
private boolean readBytes(byte buffer[], int len) {
|
||||
int off = 0, count;
|
||||
if (len < 0)
|
||||
return false;
|
||||
while (off != len) {
|
||||
try {
|
||||
count = mIn.read(buffer, off, len - off);
|
||||
if (count <= 0) {
|
||||
Slog.e(TAG, "read error " + count);
|
||||
break;
|
||||
}
|
||||
off += count;
|
||||
} catch (IOException ex) {
|
||||
Slog.e(TAG,"read exception");
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Slog.i(TAG, "read "+len+" bytes");
|
||||
if (off == len) return true;
|
||||
disconnect();
|
||||
return false;
|
||||
}
|
||||
off += count;
|
||||
} catch (IOException ex) {
|
||||
Slog.e(TAG, "read exception");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (LOCAL_DEBUG) {
|
||||
Slog.i(TAG, "read " + len + " bytes");
|
||||
}
|
||||
if (off == len)
|
||||
return true;
|
||||
disconnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean readReply() {
|
||||
int len;
|
||||
buflen = 0;
|
||||
if (!readBytes(buf, 2)) return false;
|
||||
len = (((int) buf[0]) & 0xff) | ((((int) buf[1]) & 0xff) << 8);
|
||||
if ((len < 1) || (len > 1024)) {
|
||||
Slog.e(TAG,"invalid reply length ("+len+")");
|
||||
disconnect();
|
||||
return false;
|
||||
}
|
||||
if (!readBytes(buf, len)) return false;
|
||||
buflen = len;
|
||||
return true;
|
||||
}
|
||||
private boolean readReply() {
|
||||
int len;
|
||||
buflen = 0;
|
||||
if (!readBytes(buf, 2))
|
||||
return false;
|
||||
len = (((int) buf[0]) & 0xff) | ((((int) buf[1]) & 0xff) << 8);
|
||||
if ((len < 1) || (len > 1024)) {
|
||||
Slog.e(TAG, "invalid reply length (" + len + ")");
|
||||
disconnect();
|
||||
return false;
|
||||
}
|
||||
if (!readBytes(buf, len))
|
||||
return false;
|
||||
buflen = len;
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean writeCommand(String _cmd) {
|
||||
byte[] cmd = _cmd.getBytes();
|
||||
int len = cmd.length;
|
||||
if ((len < 1) || (len > 1024)) return false;
|
||||
buf[0] = (byte) (len & 0xff);
|
||||
buf[1] = (byte) ((len >> 8) & 0xff);
|
||||
try {
|
||||
mOut.write(buf, 0, 2);
|
||||
mOut.write(cmd, 0, len);
|
||||
} catch (IOException ex) {
|
||||
Slog.e(TAG,"write error");
|
||||
disconnect();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private synchronized String transaction(String cmd) {
|
||||
if (!connect()) {
|
||||
private boolean writeCommand(String _cmd) {
|
||||
byte[] cmd = _cmd.getBytes();
|
||||
int len = cmd.length;
|
||||
if ((len < 1) || (len > 1024))
|
||||
return false;
|
||||
buf[0] = (byte) (len & 0xff);
|
||||
buf[1] = (byte) ((len >> 8) & 0xff);
|
||||
try {
|
||||
mOut.write(buf, 0, 2);
|
||||
mOut.write(cmd, 0, len);
|
||||
} catch (IOException ex) {
|
||||
Slog.e(TAG, "write error");
|
||||
disconnect();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private synchronized String transaction(String cmd) {
|
||||
if (!connect()) {
|
||||
Slog.e(TAG, "connection failed");
|
||||
return "-1";
|
||||
}
|
||||
|
||||
if (!writeCommand(cmd)) {
|
||||
/* If installd died and restarted in the background
|
||||
* (unlikely but possible) we'll fail on the next
|
||||
* write (this one). Try to reconnect and write
|
||||
* the command one more time before giving up.
|
||||
*/
|
||||
/*
|
||||
* If installd died and restarted in the background (unlikely but
|
||||
* possible) we'll fail on the next write (this one). Try to
|
||||
* reconnect and write the command one more time before giving up.
|
||||
*/
|
||||
Slog.e(TAG, "write command failed? reconnect!");
|
||||
if (!connect() || !writeCommand(cmd)) {
|
||||
return "-1";
|
||||
}
|
||||
}
|
||||
// Slog.i(TAG,"send: '"+cmd+"'");
|
||||
if (readReply()) {
|
||||
if (LOCAL_DEBUG) {
|
||||
Slog.i(TAG, "send: '" + cmd + "'");
|
||||
}
|
||||
if (readReply()) {
|
||||
String s = new String(buf, 0, buflen);
|
||||
// Slog.i(TAG,"recv: '"+s+"'");
|
||||
return s;
|
||||
} else {
|
||||
// Slog.i(TAG,"fail");
|
||||
return "-1";
|
||||
}
|
||||
}
|
||||
if (LOCAL_DEBUG) {
|
||||
Slog.i(TAG, "recv: '" + s + "'");
|
||||
}
|
||||
return s;
|
||||
} else {
|
||||
if (LOCAL_DEBUG) {
|
||||
Slog.i(TAG, "fail");
|
||||
}
|
||||
return "-1";
|
||||
}
|
||||
}
|
||||
|
||||
private int execute(String cmd) {
|
||||
String res = transaction(cmd);
|
||||
try {
|
||||
return Integer.parseInt(res);
|
||||
} catch (NumberFormatException ex) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
private int execute(String cmd) {
|
||||
String res = transaction(cmd);
|
||||
try {
|
||||
return Integer.parseInt(res);
|
||||
} catch (NumberFormatException ex) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public int install(String name, int uid, int gid) {
|
||||
StringBuilder builder = new StringBuilder("install");
|
||||
@@ -225,14 +247,14 @@ class Installer {
|
||||
builder.append(name);
|
||||
return execute(builder.toString());
|
||||
}
|
||||
|
||||
|
||||
public int clearUserData(String name) {
|
||||
StringBuilder builder = new StringBuilder("rmuserdata");
|
||||
builder.append(' ');
|
||||
builder.append(name);
|
||||
return execute(builder.toString());
|
||||
}
|
||||
|
||||
|
||||
public boolean ping() {
|
||||
if (execute("ping") < 0) {
|
||||
return false;
|
||||
@@ -240,7 +262,7 @@ class Installer {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public int freeCache(long freeStorageSize) {
|
||||
StringBuilder builder = new StringBuilder("freecache");
|
||||
builder.append(' ');
|
||||
@@ -250,8 +272,8 @@ class Installer {
|
||||
|
||||
/*
|
||||
* @param packagePathSuffix The name of the path relative to install
|
||||
* directory. Say if the path name is /data/app/com.test-1.apk,
|
||||
* the package suffix path will be com.test-1
|
||||
* directory. Say if the path name is /data/app/com.test-1.apk, the package
|
||||
* suffix path will be com.test-1
|
||||
*/
|
||||
public int setForwardLockPerm(String packagePathSuffix, int gid) {
|
||||
StringBuilder builder = new StringBuilder("protect");
|
||||
@@ -261,7 +283,7 @@ class Installer {
|
||||
builder.append(gid);
|
||||
return execute(builder.toString());
|
||||
}
|
||||
|
||||
|
||||
public int getSizeInfo(String pkgName, String apkPath, String fwdLockApkPath,
|
||||
PackageStats pStats) {
|
||||
StringBuilder builder = new StringBuilder("getsize");
|
||||
@@ -275,7 +297,7 @@ class Installer {
|
||||
String s = transaction(builder.toString());
|
||||
String res[] = s.split(" ");
|
||||
|
||||
if((res == null) || (res.length != 4)) {
|
||||
if ((res == null) || (res.length != 4)) {
|
||||
return -1;
|
||||
}
|
||||
try {
|
||||
@@ -286,7 +308,7 @@ class Installer {
|
||||
} catch (NumberFormatException e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int moveFiles() {
|
||||
return execute("movefiles");
|
||||
File diff suppressed because it is too large
Load Diff
55
services/java/com/android/server/pm/PackageSetting.java
Normal file
55
services/java/com/android/server/pm/PackageSetting.java
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.server.pm;
|
||||
|
||||
import android.content.pm.PackageParser;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Settings data for a particular package we know about.
|
||||
*/
|
||||
final class PackageSetting extends PackageSettingBase {
|
||||
int userId;
|
||||
PackageParser.Package pkg;
|
||||
SharedUserSetting sharedUser;
|
||||
|
||||
PackageSetting(String name, String realName, File codePath, File resourcePath,
|
||||
String nativeLibraryPathString, int pVersionCode, int pkgFlags) {
|
||||
super(name, realName, codePath, resourcePath, nativeLibraryPathString, pVersionCode,
|
||||
pkgFlags);
|
||||
}
|
||||
|
||||
/**
|
||||
* New instance of PackageSetting replicating the original settings.
|
||||
* Note that it keeps the same PackageParser.Package instance.
|
||||
*/
|
||||
PackageSetting(PackageSetting orig) {
|
||||
super(orig);
|
||||
|
||||
userId = orig.userId;
|
||||
pkg = orig.pkg;
|
||||
sharedUser = orig.sharedUser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PackageSetting{"
|
||||
+ Integer.toHexString(System.identityHashCode(this))
|
||||
+ " " + name + "/" + userId + "}";
|
||||
}
|
||||
}
|
||||
207
services/java/com/android/server/pm/PackageSettingBase.java
Normal file
207
services/java/com/android/server/pm/PackageSettingBase.java
Normal file
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.server.pm;
|
||||
|
||||
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
|
||||
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
|
||||
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* Settings base class for pending and resolved classes.
|
||||
*/
|
||||
class PackageSettingBase extends GrantedPermissions {
|
||||
/**
|
||||
* Indicates the state of installation. Used by PackageManager to figure out
|
||||
* incomplete installations. Say a package is being installed (the state is
|
||||
* set to PKG_INSTALL_INCOMPLETE) and remains so till the package
|
||||
* installation is successful or unsuccessful in which case the
|
||||
* PackageManager will no longer maintain state information associated with
|
||||
* the package. If some exception(like device freeze or battery being pulled
|
||||
* out) occurs during installation of a package, the PackageManager needs
|
||||
* this information to clean up the previously failed installation.
|
||||
*/
|
||||
static final int PKG_INSTALL_COMPLETE = 1;
|
||||
static final int PKG_INSTALL_INCOMPLETE = 0;
|
||||
|
||||
final String name;
|
||||
final String realName;
|
||||
File codePath;
|
||||
String codePathString;
|
||||
File resourcePath;
|
||||
String resourcePathString;
|
||||
String nativeLibraryPathString;
|
||||
long timeStamp;
|
||||
long firstInstallTime;
|
||||
long lastUpdateTime;
|
||||
int versionCode;
|
||||
|
||||
boolean uidError;
|
||||
|
||||
PackageSignatures signatures = new PackageSignatures();
|
||||
|
||||
boolean permissionsFixed;
|
||||
boolean haveGids;
|
||||
|
||||
// Whether this package is currently stopped, thus can not be
|
||||
// started until explicitly launched by the user.
|
||||
public boolean stopped;
|
||||
|
||||
// Set to true if we have never launched this app.
|
||||
public boolean notLaunched;
|
||||
|
||||
/* Explicitly disabled components */
|
||||
HashSet<String> disabledComponents = new HashSet<String>(0);
|
||||
/* Explicitly enabled components */
|
||||
HashSet<String> enabledComponents = new HashSet<String>(0);
|
||||
int enabled = COMPONENT_ENABLED_STATE_DEFAULT;
|
||||
int installStatus = PKG_INSTALL_COMPLETE;
|
||||
|
||||
PackageSettingBase origPackage;
|
||||
|
||||
/* package name of the app that installed this package */
|
||||
String installerPackageName;
|
||||
PackageSettingBase(String name, String realName, File codePath, File resourcePath,
|
||||
String nativeLibraryPathString, int pVersionCode, int pkgFlags) {
|
||||
super(pkgFlags);
|
||||
this.name = name;
|
||||
this.realName = realName;
|
||||
init(codePath, resourcePath, nativeLibraryPathString, pVersionCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* New instance of PackageSetting with one-level-deep cloning.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
PackageSettingBase(PackageSettingBase base) {
|
||||
super(base);
|
||||
|
||||
name = base.name;
|
||||
realName = base.realName;
|
||||
codePath = base.codePath;
|
||||
codePathString = base.codePathString;
|
||||
resourcePath = base.resourcePath;
|
||||
resourcePathString = base.resourcePathString;
|
||||
nativeLibraryPathString = base.nativeLibraryPathString;
|
||||
timeStamp = base.timeStamp;
|
||||
firstInstallTime = base.firstInstallTime;
|
||||
lastUpdateTime = base.lastUpdateTime;
|
||||
versionCode = base.versionCode;
|
||||
|
||||
uidError = base.uidError;
|
||||
|
||||
signatures = new PackageSignatures(base.signatures);
|
||||
|
||||
permissionsFixed = base.permissionsFixed;
|
||||
haveGids = base.haveGids;
|
||||
stopped = base.stopped;
|
||||
notLaunched = base.notLaunched;
|
||||
|
||||
disabledComponents = (HashSet<String>) base.disabledComponents.clone();
|
||||
|
||||
enabledComponents = (HashSet<String>) base.enabledComponents.clone();
|
||||
|
||||
enabled = base.enabled;
|
||||
installStatus = base.installStatus;
|
||||
|
||||
origPackage = base.origPackage;
|
||||
|
||||
installerPackageName = base.installerPackageName;
|
||||
}
|
||||
|
||||
void init(File codePath, File resourcePath, String nativeLibraryPathString,
|
||||
int pVersionCode) {
|
||||
this.codePath = codePath;
|
||||
this.codePathString = codePath.toString();
|
||||
this.resourcePath = resourcePath;
|
||||
this.resourcePathString = resourcePath.toString();
|
||||
this.nativeLibraryPathString = nativeLibraryPathString;
|
||||
this.versionCode = pVersionCode;
|
||||
}
|
||||
|
||||
public void setInstallerPackageName(String packageName) {
|
||||
installerPackageName = packageName;
|
||||
}
|
||||
|
||||
String getInstallerPackageName() {
|
||||
return installerPackageName;
|
||||
}
|
||||
|
||||
public void setInstallStatus(int newStatus) {
|
||||
installStatus = newStatus;
|
||||
}
|
||||
|
||||
public int getInstallStatus() {
|
||||
return installStatus;
|
||||
}
|
||||
|
||||
public void setTimeStamp(long newStamp) {
|
||||
timeStamp = newStamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a shallow copy of this package settings.
|
||||
*/
|
||||
public void copyFrom(PackageSettingBase base) {
|
||||
grantedPermissions = base.grantedPermissions;
|
||||
gids = base.gids;
|
||||
|
||||
timeStamp = base.timeStamp;
|
||||
firstInstallTime = base.firstInstallTime;
|
||||
lastUpdateTime = base.lastUpdateTime;
|
||||
signatures = base.signatures;
|
||||
permissionsFixed = base.permissionsFixed;
|
||||
haveGids = base.haveGids;
|
||||
stopped = base.stopped;
|
||||
notLaunched = base.notLaunched;
|
||||
disabledComponents = base.disabledComponents;
|
||||
enabledComponents = base.enabledComponents;
|
||||
enabled = base.enabled;
|
||||
installStatus = base.installStatus;
|
||||
}
|
||||
|
||||
boolean enableComponentLPw(String componentClassName) {
|
||||
boolean changed = disabledComponents.remove(componentClassName);
|
||||
changed |= enabledComponents.add(componentClassName);
|
||||
return changed;
|
||||
}
|
||||
|
||||
boolean disableComponentLPw(String componentClassName) {
|
||||
boolean changed = enabledComponents.remove(componentClassName);
|
||||
changed |= disabledComponents.add(componentClassName);
|
||||
return changed;
|
||||
}
|
||||
|
||||
boolean restoreComponentLPw(String componentClassName) {
|
||||
boolean changed = enabledComponents.remove(componentClassName);
|
||||
changed |= disabledComponents.remove(componentClassName);
|
||||
return changed;
|
||||
}
|
||||
|
||||
int getCurrentEnabledStateLPr(String componentName) {
|
||||
if (enabledComponents.contains(componentName)) {
|
||||
return COMPONENT_ENABLED_STATE_ENABLED;
|
||||
} else if (disabledComponents.contains(componentName)) {
|
||||
return COMPONENT_ENABLED_STATE_DISABLED;
|
||||
} else {
|
||||
return COMPONENT_ENABLED_STATE_DEFAULT;
|
||||
}
|
||||
}
|
||||
}
|
||||
198
services/java/com/android/server/pm/PackageSignatures.java
Normal file
198
services/java/com/android/server/pm/PackageSignatures.java
Normal file
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.server.pm;
|
||||
|
||||
import com.android.internal.util.XmlUtils;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
|
||||
import android.content.pm.Signature;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
class PackageSignatures {
|
||||
Signature[] mSignatures;
|
||||
|
||||
PackageSignatures(PackageSignatures orig) {
|
||||
if (orig != null && orig.mSignatures != null) {
|
||||
mSignatures = orig.mSignatures.clone();
|
||||
}
|
||||
}
|
||||
|
||||
PackageSignatures(Signature[] sigs) {
|
||||
assignSignatures(sigs);
|
||||
}
|
||||
|
||||
PackageSignatures() {
|
||||
}
|
||||
|
||||
void writeXml(XmlSerializer serializer, String tagName,
|
||||
ArrayList<Signature> pastSignatures) throws IOException {
|
||||
if (mSignatures == null) {
|
||||
return;
|
||||
}
|
||||
serializer.startTag(null, tagName);
|
||||
serializer.attribute(null, "count",
|
||||
Integer.toString(mSignatures.length));
|
||||
for (int i=0; i<mSignatures.length; i++) {
|
||||
serializer.startTag(null, "cert");
|
||||
final Signature sig = mSignatures[i];
|
||||
final int sigHash = sig.hashCode();
|
||||
final int numPast = pastSignatures.size();
|
||||
int j;
|
||||
for (j=0; j<numPast; j++) {
|
||||
Signature pastSig = pastSignatures.get(j);
|
||||
if (pastSig.hashCode() == sigHash && pastSig.equals(sig)) {
|
||||
serializer.attribute(null, "index", Integer.toString(j));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j >= numPast) {
|
||||
pastSignatures.add(sig);
|
||||
serializer.attribute(null, "index", Integer.toString(numPast));
|
||||
serializer.attribute(null, "key", sig.toCharsString());
|
||||
}
|
||||
serializer.endTag(null, "cert");
|
||||
}
|
||||
serializer.endTag(null, tagName);
|
||||
}
|
||||
|
||||
void readXml(XmlPullParser parser, ArrayList<Signature> pastSignatures)
|
||||
throws IOException, XmlPullParserException {
|
||||
String countStr = parser.getAttributeValue(null, "count");
|
||||
if (countStr == null) {
|
||||
PackageManagerService.reportSettingsProblem(Log.WARN,
|
||||
"Error in package manager settings: <signatures> has"
|
||||
+ " no count at " + parser.getPositionDescription());
|
||||
XmlUtils.skipCurrentTag(parser);
|
||||
}
|
||||
final int count = Integer.parseInt(countStr);
|
||||
mSignatures = new Signature[count];
|
||||
int pos = 0;
|
||||
|
||||
int outerDepth = parser.getDepth();
|
||||
int type;
|
||||
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
|
||||
&& (type != XmlPullParser.END_TAG
|
||||
|| parser.getDepth() > outerDepth)) {
|
||||
if (type == XmlPullParser.END_TAG
|
||||
|| type == XmlPullParser.TEXT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String tagName = parser.getName();
|
||||
if (tagName.equals("cert")) {
|
||||
if (pos < count) {
|
||||
String index = parser.getAttributeValue(null, "index");
|
||||
if (index != null) {
|
||||
try {
|
||||
int idx = Integer.parseInt(index);
|
||||
String key = parser.getAttributeValue(null, "key");
|
||||
if (key == null) {
|
||||
if (idx >= 0 && idx < pastSignatures.size()) {
|
||||
Signature sig = pastSignatures.get(idx);
|
||||
if (sig != null) {
|
||||
mSignatures[pos] = pastSignatures.get(idx);
|
||||
pos++;
|
||||
} else {
|
||||
PackageManagerService.reportSettingsProblem(Log.WARN,
|
||||
"Error in package manager settings: <cert> "
|
||||
+ "index " + index + " is not defined at "
|
||||
+ parser.getPositionDescription());
|
||||
}
|
||||
} else {
|
||||
PackageManagerService.reportSettingsProblem(Log.WARN,
|
||||
"Error in package manager settings: <cert> "
|
||||
+ "index " + index + " is out of bounds at "
|
||||
+ parser.getPositionDescription());
|
||||
}
|
||||
} else {
|
||||
while (pastSignatures.size() <= idx) {
|
||||
pastSignatures.add(null);
|
||||
}
|
||||
Signature sig = new Signature(key);
|
||||
pastSignatures.set(idx, sig);
|
||||
mSignatures[pos] = sig;
|
||||
pos++;
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
PackageManagerService.reportSettingsProblem(Log.WARN,
|
||||
"Error in package manager settings: <cert> "
|
||||
+ "index " + index + " is not a number at "
|
||||
+ parser.getPositionDescription());
|
||||
}
|
||||
} else {
|
||||
PackageManagerService.reportSettingsProblem(Log.WARN,
|
||||
"Error in package manager settings: <cert> has"
|
||||
+ " no index at " + parser.getPositionDescription());
|
||||
}
|
||||
} else {
|
||||
PackageManagerService.reportSettingsProblem(Log.WARN,
|
||||
"Error in package manager settings: too "
|
||||
+ "many <cert> tags, expected " + count
|
||||
+ " at " + parser.getPositionDescription());
|
||||
}
|
||||
} else {
|
||||
PackageManagerService.reportSettingsProblem(Log.WARN,
|
||||
"Unknown element under <cert>: "
|
||||
+ parser.getName());
|
||||
}
|
||||
XmlUtils.skipCurrentTag(parser);
|
||||
}
|
||||
|
||||
if (pos < count) {
|
||||
// Should never happen -- there is an error in the written
|
||||
// settings -- but if it does we don't want to generate
|
||||
// a bad array.
|
||||
Signature[] newSigs = new Signature[pos];
|
||||
System.arraycopy(mSignatures, 0, newSigs, 0, pos);
|
||||
mSignatures = newSigs;
|
||||
}
|
||||
}
|
||||
|
||||
void assignSignatures(Signature[] sigs) {
|
||||
if (sigs == null) {
|
||||
mSignatures = null;
|
||||
return;
|
||||
}
|
||||
mSignatures = new Signature[sigs.length];
|
||||
for (int i=0; i<sigs.length; i++) {
|
||||
mSignatures[i] = sigs[i];
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuffer buf = new StringBuffer(128);
|
||||
buf.append("PackageSignatures{");
|
||||
buf.append(Integer.toHexString(System.identityHashCode(this)));
|
||||
buf.append(" [");
|
||||
if (mSignatures != null) {
|
||||
for (int i=0; i<mSignatures.length; i++) {
|
||||
if (i > 0) buf.append(", ");
|
||||
buf.append(Integer.toHexString(
|
||||
System.identityHashCode(mSignatures[i])));
|
||||
}
|
||||
}
|
||||
buf.append("]}");
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
30
services/java/com/android/server/pm/PendingPackage.java
Normal file
30
services/java/com/android/server/pm/PendingPackage.java
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.server.pm;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
final class PendingPackage extends PackageSettingBase {
|
||||
final int sharedId;
|
||||
|
||||
PendingPackage(String name, String realName, File codePath, File resourcePath,
|
||||
String nativeLibraryPathString, int sharedId, int pVersionCode, int pkgFlags) {
|
||||
super(name, realName, codePath, resourcePath, nativeLibraryPathString, pVersionCode,
|
||||
pkgFlags);
|
||||
this.sharedId = sharedId;
|
||||
}
|
||||
}
|
||||
73
services/java/com/android/server/pm/PreferredActivity.java
Normal file
73
services/java/com/android/server/pm/PreferredActivity.java
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.server.pm;
|
||||
|
||||
import com.android.internal.util.XmlUtils;
|
||||
import com.android.server.PreferredComponent;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.IntentFilter;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
class PreferredActivity extends IntentFilter implements PreferredComponent.Callbacks {
|
||||
private static final String TAG = "PreferredActivity";
|
||||
|
||||
private static final boolean DEBUG_FILTERS = false;
|
||||
|
||||
final PreferredComponent mPref;
|
||||
|
||||
PreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity) {
|
||||
super(filter);
|
||||
mPref = new PreferredComponent(this, match, set, activity);
|
||||
}
|
||||
|
||||
PreferredActivity(XmlPullParser parser) throws XmlPullParserException, IOException {
|
||||
mPref = new PreferredComponent(this, parser);
|
||||
}
|
||||
|
||||
public void writeToXml(XmlSerializer serializer) throws IOException {
|
||||
mPref.writeToXml(serializer);
|
||||
serializer.startTag(null, "filter");
|
||||
super.writeToXml(serializer);
|
||||
serializer.endTag(null, "filter");
|
||||
}
|
||||
|
||||
public boolean onReadTag(String tagName, XmlPullParser parser) throws XmlPullParserException,
|
||||
IOException {
|
||||
if (tagName.equals("filter")) {
|
||||
if (DEBUG_FILTERS) {
|
||||
Log.i(TAG, "Starting to parse filter...");
|
||||
}
|
||||
readFromXml(parser);
|
||||
if (DEBUG_FILTERS) {
|
||||
Log.i(TAG, "Finished filter: depth=" + parser.getDepth() + " tag="
|
||||
+ parser.getName());
|
||||
}
|
||||
} else {
|
||||
PackageManagerService.reportSettingsProblem(Log.WARN,
|
||||
"Unknown element under <preferred-activities>: " + parser.getName());
|
||||
XmlUtils.skipCurrentTag(parser);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
2224
services/java/com/android/server/pm/Settings.java
Normal file
2224
services/java/com/android/server/pm/Settings.java
Normal file
File diff suppressed because it is too large
Load Diff
43
services/java/com/android/server/pm/SharedUserSetting.java
Normal file
43
services/java/com/android/server/pm/SharedUserSetting.java
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.server.pm;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* Settings data for a particular shared user ID we know about.
|
||||
*/
|
||||
final class SharedUserSetting extends GrantedPermissions {
|
||||
final String name;
|
||||
|
||||
int userId;
|
||||
|
||||
final HashSet<PackageSetting> packages = new HashSet<PackageSetting>();
|
||||
|
||||
final PackageSignatures signatures = new PackageSignatures();
|
||||
|
||||
SharedUserSetting(String _name, int _pkgFlags) {
|
||||
super(_pkgFlags);
|
||||
name = _name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SharedUserSetting{" + Integer.toHexString(System.identityHashCode(this)) + " "
|
||||
+ name + "/" + userId + "}";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user