Split PackageManagerService into subclasses
Split PackageManagerService from one monolithic class with several inner classes to several classes. This will help determining how its data structures can be reshuffled to provide better separation of concerns. Change-Id: Ic7571daebdcf13ce08e08f34204c5bbf4140139b
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 enableComponentLP(String componentClassName) {
|
||||
boolean changed = disabledComponents.remove(componentClassName);
|
||||
changed |= enabledComponents.add(componentClassName);
|
||||
return changed;
|
||||
}
|
||||
|
||||
boolean disableComponentLP(String componentClassName) {
|
||||
boolean changed = enabledComponents.remove(componentClassName);
|
||||
changed |= disabledComponents.add(componentClassName);
|
||||
return changed;
|
||||
}
|
||||
|
||||
boolean restoreComponentLP(String componentClassName) {
|
||||
boolean changed = enabledComponents.remove(componentClassName);
|
||||
changed |= disabledComponents.remove(componentClassName);
|
||||
return changed;
|
||||
}
|
||||
|
||||
int currentEnabledStateLP(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;
|
||||
}
|
||||
}
|
||||
1913
services/java/com/android/server/pm/Settings.java
Normal file
1913
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