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
|
* settings parameter with a default value of 2MB), the free memory is
|
||||||
* logged to the event log.
|
* logged to the event log.
|
||||||
*/
|
*/
|
||||||
class DeviceStorageMonitorService extends Binder {
|
public class DeviceStorageMonitorService extends Binder {
|
||||||
private static final String TAG = "DeviceStorageMonitorService";
|
private static final String TAG = "DeviceStorageMonitorService";
|
||||||
private static final boolean DEBUG = false;
|
private static final boolean DEBUG = false;
|
||||||
private static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV;
|
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.
|
* 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
|
* 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.internal.app.IMediaContainerService;
|
||||||
import com.android.server.am.ActivityManagerService;
|
import com.android.server.am.ActivityManagerService;
|
||||||
|
import com.android.server.pm.PackageManagerService;
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
@ -86,6 +87,9 @@ class MountService extends IMountService.Stub implements INativeDaemonConnectorC
|
|||||||
|
|
||||||
private static final String VOLD_TAG = "VoldConnector";
|
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
|
* Internal vold volume state constants
|
||||||
*/
|
*/
|
||||||
@ -483,7 +487,6 @@ class MountService extends IMountService.Stub implements INativeDaemonConnectorC
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private final class MountServiceBinderListener implements IBinder.DeathRecipient {
|
private final class MountServiceBinderListener implements IBinder.DeathRecipient {
|
||||||
final IMountServiceListener mListener;
|
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
|
* amount of containers we'd ever expect to have. This keeps an
|
||||||
* "asec list" from blocking a thread repeatedly.
|
* "asec list" from blocking a thread repeatedly.
|
||||||
*/
|
*/
|
||||||
mConnector = new NativeDaemonConnector(this, "vold",
|
mConnector = new NativeDaemonConnector(this, "vold", MAX_CONTAINERS * 2, VOLD_TAG);
|
||||||
PackageManagerService.MAX_CONTAINERS * 2, VOLD_TAG);
|
|
||||||
mReady = false;
|
mReady = false;
|
||||||
Thread thread = new Thread(mConnector, VOLD_TAG);
|
Thread thread = new Thread(mConnector, VOLD_TAG);
|
||||||
thread.start();
|
thread.start();
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
package com.android.server;
|
package com.android.server;
|
||||||
|
|
||||||
import com.android.server.am.ActivityManagerService;
|
import com.android.server.am.ActivityManagerService;
|
||||||
|
import com.android.server.pm.PackageManagerService;
|
||||||
import com.android.server.usb.UsbService;
|
import com.android.server.usb.UsbService;
|
||||||
import com.android.server.wm.WindowManagerService;
|
import com.android.server.wm.WindowManagerService;
|
||||||
import com.android.internal.app.ShutdownThread;
|
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.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.server;
|
package com.android.server.pm;
|
||||||
|
|
||||||
import android.content.pm.PackageStats;
|
import android.content.pm.PackageStats;
|
||||||
import android.net.LocalSocketAddress;
|
|
||||||
import android.net.LocalSocket;
|
import android.net.LocalSocket;
|
||||||
import android.util.Config;
|
import android.net.LocalSocketAddress;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.Socket;
|
|
||||||
|
|
||||||
|
|
||||||
class Installer {
|
class Installer {
|
||||||
private static final String TAG = "Installer";
|
private static final String TAG = "Installer";
|
||||||
InputStream mIn;
|
|
||||||
OutputStream mOut;
|
|
||||||
LocalSocket mSocket;
|
|
||||||
|
|
||||||
byte buf[] = new byte[1024];
|
private static final boolean LOCAL_DEBUG = true;
|
||||||
int buflen = 0;
|
|
||||||
|
InputStream mIn;
|
||||||
|
|
||||||
|
OutputStream mOut;
|
||||||
|
|
||||||
|
LocalSocket mSocket;
|
||||||
|
|
||||||
|
byte buf[] = new byte[1024];
|
||||||
|
|
||||||
|
int buflen = 0;
|
||||||
|
|
||||||
private boolean connect() {
|
private boolean connect() {
|
||||||
if (mSocket != null) {
|
if (mSocket != null) {
|
||||||
@ -45,8 +48,8 @@ class Installer {
|
|||||||
try {
|
try {
|
||||||
mSocket = new LocalSocket();
|
mSocket = new LocalSocket();
|
||||||
|
|
||||||
LocalSocketAddress address = new LocalSocketAddress(
|
LocalSocketAddress address = new LocalSocketAddress("installd",
|
||||||
"installd", LocalSocketAddress.Namespace.RESERVED);
|
LocalSocketAddress.Namespace.RESERVED);
|
||||||
|
|
||||||
mSocket.connect(address);
|
mSocket.connect(address);
|
||||||
|
|
||||||
@ -59,112 +62,131 @@ class Installer {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void disconnect() {
|
private void disconnect() {
|
||||||
Slog.i(TAG,"disconnecting...");
|
Slog.i(TAG, "disconnecting...");
|
||||||
try {
|
try {
|
||||||
if (mSocket != null) mSocket.close();
|
if (mSocket != null)
|
||||||
} catch (IOException ex) { }
|
mSocket.close();
|
||||||
try {
|
} catch (IOException ex) {
|
||||||
if (mIn != null) mIn.close();
|
}
|
||||||
} catch (IOException ex) { }
|
try {
|
||||||
try {
|
if (mIn != null)
|
||||||
if (mOut != null) mOut.close();
|
mIn.close();
|
||||||
} catch (IOException ex) { }
|
} catch (IOException ex) {
|
||||||
mSocket = null;
|
}
|
||||||
mIn = null;
|
try {
|
||||||
mOut = null;
|
if (mOut != null)
|
||||||
}
|
mOut.close();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
}
|
||||||
|
mSocket = null;
|
||||||
|
mIn = null;
|
||||||
|
mOut = null;
|
||||||
|
}
|
||||||
|
|
||||||
private boolean readBytes(byte buffer[], int len) {
|
private boolean readBytes(byte buffer[], int len) {
|
||||||
int off = 0, count;
|
int off = 0, count;
|
||||||
if (len < 0) return false;
|
if (len < 0)
|
||||||
while (off != len) {
|
return false;
|
||||||
try {
|
while (off != len) {
|
||||||
count = mIn.read(buffer, off, len - off);
|
try {
|
||||||
if (count <= 0) {
|
count = mIn.read(buffer, off, len - off);
|
||||||
|
if (count <= 0) {
|
||||||
Slog.e(TAG, "read error " + count);
|
Slog.e(TAG, "read error " + count);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
off += count;
|
off += count;
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
Slog.e(TAG,"read exception");
|
Slog.e(TAG, "read exception");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Slog.i(TAG, "read "+len+" bytes");
|
if (LOCAL_DEBUG) {
|
||||||
if (off == len) return true;
|
Slog.i(TAG, "read " + len + " bytes");
|
||||||
disconnect();
|
}
|
||||||
return false;
|
if (off == len)
|
||||||
}
|
return true;
|
||||||
|
disconnect();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private boolean readReply() {
|
private boolean readReply() {
|
||||||
int len;
|
int len;
|
||||||
buflen = 0;
|
buflen = 0;
|
||||||
if (!readBytes(buf, 2)) return false;
|
if (!readBytes(buf, 2))
|
||||||
len = (((int) buf[0]) & 0xff) | ((((int) buf[1]) & 0xff) << 8);
|
return false;
|
||||||
if ((len < 1) || (len > 1024)) {
|
len = (((int) buf[0]) & 0xff) | ((((int) buf[1]) & 0xff) << 8);
|
||||||
Slog.e(TAG,"invalid reply length ("+len+")");
|
if ((len < 1) || (len > 1024)) {
|
||||||
disconnect();
|
Slog.e(TAG, "invalid reply length (" + len + ")");
|
||||||
return false;
|
disconnect();
|
||||||
}
|
return false;
|
||||||
if (!readBytes(buf, len)) return false;
|
}
|
||||||
buflen = len;
|
if (!readBytes(buf, len))
|
||||||
return true;
|
return false;
|
||||||
}
|
buflen = len;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private boolean writeCommand(String _cmd) {
|
private boolean writeCommand(String _cmd) {
|
||||||
byte[] cmd = _cmd.getBytes();
|
byte[] cmd = _cmd.getBytes();
|
||||||
int len = cmd.length;
|
int len = cmd.length;
|
||||||
if ((len < 1) || (len > 1024)) return false;
|
if ((len < 1) || (len > 1024))
|
||||||
buf[0] = (byte) (len & 0xff);
|
return false;
|
||||||
buf[1] = (byte) ((len >> 8) & 0xff);
|
buf[0] = (byte) (len & 0xff);
|
||||||
try {
|
buf[1] = (byte) ((len >> 8) & 0xff);
|
||||||
mOut.write(buf, 0, 2);
|
try {
|
||||||
mOut.write(cmd, 0, len);
|
mOut.write(buf, 0, 2);
|
||||||
} catch (IOException ex) {
|
mOut.write(cmd, 0, len);
|
||||||
Slog.e(TAG,"write error");
|
} catch (IOException ex) {
|
||||||
disconnect();
|
Slog.e(TAG, "write error");
|
||||||
return false;
|
disconnect();
|
||||||
}
|
return false;
|
||||||
return true;
|
}
|
||||||
}
|
return true;
|
||||||
|
}
|
||||||
private synchronized String transaction(String cmd) {
|
|
||||||
if (!connect()) {
|
private synchronized String transaction(String cmd) {
|
||||||
|
if (!connect()) {
|
||||||
Slog.e(TAG, "connection failed");
|
Slog.e(TAG, "connection failed");
|
||||||
return "-1";
|
return "-1";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!writeCommand(cmd)) {
|
if (!writeCommand(cmd)) {
|
||||||
/* If installd died and restarted in the background
|
/*
|
||||||
* (unlikely but possible) we'll fail on the next
|
* If installd died and restarted in the background (unlikely but
|
||||||
* write (this one). Try to reconnect and write
|
* possible) we'll fail on the next write (this one). Try to
|
||||||
* the command one more time before giving up.
|
* reconnect and write the command one more time before giving up.
|
||||||
*/
|
*/
|
||||||
Slog.e(TAG, "write command failed? reconnect!");
|
Slog.e(TAG, "write command failed? reconnect!");
|
||||||
if (!connect() || !writeCommand(cmd)) {
|
if (!connect() || !writeCommand(cmd)) {
|
||||||
return "-1";
|
return "-1";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Slog.i(TAG,"send: '"+cmd+"'");
|
if (LOCAL_DEBUG) {
|
||||||
if (readReply()) {
|
Slog.i(TAG, "send: '" + cmd + "'");
|
||||||
|
}
|
||||||
|
if (readReply()) {
|
||||||
String s = new String(buf, 0, buflen);
|
String s = new String(buf, 0, buflen);
|
||||||
// Slog.i(TAG,"recv: '"+s+"'");
|
if (LOCAL_DEBUG) {
|
||||||
return s;
|
Slog.i(TAG, "recv: '" + s + "'");
|
||||||
} else {
|
}
|
||||||
// Slog.i(TAG,"fail");
|
return s;
|
||||||
return "-1";
|
} else {
|
||||||
}
|
if (LOCAL_DEBUG) {
|
||||||
}
|
Slog.i(TAG, "fail");
|
||||||
|
}
|
||||||
|
return "-1";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private int execute(String cmd) {
|
private int execute(String cmd) {
|
||||||
String res = transaction(cmd);
|
String res = transaction(cmd);
|
||||||
try {
|
try {
|
||||||
return Integer.parseInt(res);
|
return Integer.parseInt(res);
|
||||||
} catch (NumberFormatException ex) {
|
} catch (NumberFormatException ex) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int install(String name, int uid, int gid) {
|
public int install(String name, int uid, int gid) {
|
||||||
StringBuilder builder = new StringBuilder("install");
|
StringBuilder builder = new StringBuilder("install");
|
||||||
@ -225,14 +247,14 @@ class Installer {
|
|||||||
builder.append(name);
|
builder.append(name);
|
||||||
return execute(builder.toString());
|
return execute(builder.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public int clearUserData(String name) {
|
public int clearUserData(String name) {
|
||||||
StringBuilder builder = new StringBuilder("rmuserdata");
|
StringBuilder builder = new StringBuilder("rmuserdata");
|
||||||
builder.append(' ');
|
builder.append(' ');
|
||||||
builder.append(name);
|
builder.append(name);
|
||||||
return execute(builder.toString());
|
return execute(builder.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean ping() {
|
public boolean ping() {
|
||||||
if (execute("ping") < 0) {
|
if (execute("ping") < 0) {
|
||||||
return false;
|
return false;
|
||||||
@ -240,7 +262,7 @@ class Installer {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int freeCache(long freeStorageSize) {
|
public int freeCache(long freeStorageSize) {
|
||||||
StringBuilder builder = new StringBuilder("freecache");
|
StringBuilder builder = new StringBuilder("freecache");
|
||||||
builder.append(' ');
|
builder.append(' ');
|
||||||
@ -250,8 +272,8 @@ class Installer {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* @param packagePathSuffix The name of the path relative to install
|
* @param packagePathSuffix The name of the path relative to install
|
||||||
* directory. Say if the path name is /data/app/com.test-1.apk,
|
* directory. Say if the path name is /data/app/com.test-1.apk, the package
|
||||||
* the package suffix path will be com.test-1
|
* suffix path will be com.test-1
|
||||||
*/
|
*/
|
||||||
public int setForwardLockPerm(String packagePathSuffix, int gid) {
|
public int setForwardLockPerm(String packagePathSuffix, int gid) {
|
||||||
StringBuilder builder = new StringBuilder("protect");
|
StringBuilder builder = new StringBuilder("protect");
|
||||||
@ -261,7 +283,7 @@ class Installer {
|
|||||||
builder.append(gid);
|
builder.append(gid);
|
||||||
return execute(builder.toString());
|
return execute(builder.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSizeInfo(String pkgName, String apkPath, String fwdLockApkPath,
|
public int getSizeInfo(String pkgName, String apkPath, String fwdLockApkPath,
|
||||||
PackageStats pStats) {
|
PackageStats pStats) {
|
||||||
StringBuilder builder = new StringBuilder("getsize");
|
StringBuilder builder = new StringBuilder("getsize");
|
||||||
@ -275,7 +297,7 @@ class Installer {
|
|||||||
String s = transaction(builder.toString());
|
String s = transaction(builder.toString());
|
||||||
String res[] = s.split(" ");
|
String res[] = s.split(" ");
|
||||||
|
|
||||||
if((res == null) || (res.length != 4)) {
|
if ((res == null) || (res.length != 4)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@ -286,7 +308,7 @@ class Installer {
|
|||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int moveFiles() {
|
public int moveFiles() {
|
||||||
return execute("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