summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
Diffstat (limited to 'services')
-rw-r--r--services/core/java/com/android/server/AlarmManagerService.java12
-rw-r--r--services/core/java/com/android/server/AssetAtlasService.java28
-rw-r--r--services/core/java/com/android/server/ConsumerIrService.java22
-rw-r--r--services/core/java/com/android/server/LocationManagerService.java3
-rw-r--r--services/core/java/com/android/server/MountService.java49
-rw-r--r--services/core/java/com/android/server/NetworkManagementService.java16
-rw-r--r--services/core/java/com/android/server/TelephonyRegistry.java179
-rwxr-xr-x[-rw-r--r--]services/core/java/com/android/server/am/ActiveServices.java1
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java49
-rwxr-xr-x[-rw-r--r--]services/core/java/com/android/server/am/ActivityRecord.java2
-rwxr-xr-xservices/core/java/com/android/server/am/ActivityStack.java4
-rw-r--r--services/core/java/com/android/server/am/CoreSettingsObserver.java58
-rw-r--r--services/core/java/com/android/server/am/NativeCrashListener.java38
-rw-r--r--services/core/java/com/android/server/am/UsageStatsService.java262
-rw-r--r--services/core/java/com/android/server/firewall/IntentFirewall.java10
-rw-r--r--services/core/java/com/android/server/lights/LightsService.java1
-rw-r--r--services/core/java/com/android/server/pm/Installer.java54
-rwxr-xr-xservices/core/java/com/android/server/pm/PackageManagerService.java719
-rw-r--r--services/core/java/com/android/server/pm/PackageSetting.java4
-rw-r--r--services/core/java/com/android/server/pm/PackageSettingBase.java10
-rw-r--r--services/core/java/com/android/server/pm/PendingPackage.java4
-rw-r--r--services/core/java/com/android/server/pm/SELinuxMMAC.java104
-rw-r--r--services/core/java/com/android/server/pm/Settings.java47
-rw-r--r--services/core/java/com/android/server/updates/SELinuxPolicyInstallReceiver.java16
-rw-r--r--services/core/java/com/android/server/wm/ScreenRotationAnimation.java12
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java17
-rw-r--r--services/core/jni/com_android_server_AlarmManagerService.cpp90
-rw-r--r--services/core/jni/com_android_server_AssetAtlasService.cpp44
-rw-r--r--services/core/jni/com_android_server_ConsumerIrService.cpp16
-rw-r--r--services/core/jni/com_android_server_UsbHostManager.cpp4
-rw-r--r--services/java/com/android/server/SystemServer.java6
-rw-r--r--services/usb/java/com/android/server/usb/UsbDeviceManager.java7
32 files changed, 1436 insertions, 452 deletions
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 96063d5..c14ed8b 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -656,12 +656,19 @@ class AlarmManagerService extends SystemService {
}
@Override
- public void setTime(long millis) {
+ public boolean setTime(long millis) {
getContext().enforceCallingOrSelfPermission(
"android.permission.SET_TIME",
"setTime");
- SystemClock.setCurrentTimeMillis(millis);
+ if (mNativeData == 0) {
+ Slog.w(TAG, "Not setting time since no alarm driver is available.");
+ return false;
+ }
+
+ synchronized (mLock) {
+ return setKernelTime(mNativeData, millis) == 0;
+ }
}
@Override
@@ -1039,6 +1046,7 @@ class AlarmManagerService extends SystemService {
private native void close(long nativeData);
private native void set(long nativeData, int type, long seconds, long nanoseconds);
private native int waitForAlarm(long nativeData);
+ private native int setKernelTime(long nativeData, long millis);
private native int setKernelTimezone(long nativeData, int minuteswest);
void triggerAlarmsLocked(ArrayList<Alarm> triggerList, long nowELAPSED, long nowRTC) {
diff --git a/services/core/java/com/android/server/AssetAtlasService.java b/services/core/java/com/android/server/AssetAtlasService.java
index 3fb006b..fc4838c 100644
--- a/services/core/java/com/android/server/AssetAtlasService.java
+++ b/services/core/java/com/android/server/AssetAtlasService.java
@@ -114,12 +114,11 @@ public class AssetAtlasService extends IAssetAtlas.Stub {
// Describes how bitmaps are placed in the atlas. Each bitmap is
// represented by several entries in the array:
- // int0: SkBitmap*, the native bitmap object
- // int1: x position
- // int2: y position
- // int3: rotated, 1 if the bitmap must be rotated, 0 otherwise
- // NOTE: This will need to be handled differently to support 64 bit pointers
- private int[] mAtlasMap;
+ // long0: SkBitmap*, the native bitmap object
+ // long1: x position
+ // long2: y position
+ // long3: rotated, 1 if the bitmap must be rotated, 0 otherwise
+ private long[] mAtlasMap;
/**
* Creates a new service. Upon creating, the service will gather the list of
@@ -196,7 +195,7 @@ public class AssetAtlasService extends IAssetAtlas.Stub {
private final ArrayList<Bitmap> mBitmaps;
private final int mPixelCount;
- private int mNativeBitmap;
+ private long mNativeBitmap;
// Used for debugging only
private Bitmap mAtlasBitmap;
@@ -260,8 +259,8 @@ public class AssetAtlasService extends IAssetAtlas.Stub {
final Atlas.Entry entry = new Atlas.Entry();
- mAtlasMap = new int[packCount * ATLAS_MAP_ENTRY_FIELD_COUNT];
- int[] atlasMap = mAtlasMap;
+ mAtlasMap = new long[packCount * ATLAS_MAP_ENTRY_FIELD_COUNT];
+ long[] atlasMap = mAtlasMap;
int mapIndex = 0;
boolean result = false;
@@ -288,8 +287,7 @@ public class AssetAtlasService extends IAssetAtlas.Stub {
}
canvas.drawBitmap(bitmap, 0.0f, 0.0f, null);
canvas.restore();
- // TODO: Change mAtlasMap to long[] to support 64-bit systems
- atlasMap[mapIndex++] = (int) bitmap.mNativeBitmap;
+ atlasMap[mapIndex++] = bitmap.mNativeBitmap;
atlasMap[mapIndex++] = entry.x;
atlasMap[mapIndex++] = entry.y;
atlasMap[mapIndex++] = entry.rotated ? 1 : 0;
@@ -365,9 +363,9 @@ public class AssetAtlasService extends IAssetAtlas.Stub {
}
}
- private static native int nAcquireAtlasCanvas(Canvas canvas, int width, int height);
- private static native void nReleaseAtlasCanvas(Canvas canvas, int bitmap);
- private static native boolean nUploadAtlas(GraphicBuffer buffer, int bitmap);
+ private static native long nAcquireAtlasCanvas(Canvas canvas, int width, int height);
+ private static native void nReleaseAtlasCanvas(Canvas canvas, long bitmap);
+ private static native boolean nUploadAtlas(GraphicBuffer buffer, long bitmap);
@Override
public boolean isCompatible(int ppid) {
@@ -380,7 +378,7 @@ public class AssetAtlasService extends IAssetAtlas.Stub {
}
@Override
- public int[] getMap() throws RemoteException {
+ public long[] getMap() throws RemoteException {
return mAtlasReady.get() ? mAtlasMap : null;
}
diff --git a/services/core/java/com/android/server/ConsumerIrService.java b/services/core/java/com/android/server/ConsumerIrService.java
index 783dff1..583f1bc 100644
--- a/services/core/java/com/android/server/ConsumerIrService.java
+++ b/services/core/java/com/android/server/ConsumerIrService.java
@@ -49,13 +49,13 @@ public class ConsumerIrService extends IConsumerIrService.Stub {
private static final int MAX_XMIT_TIME = 2000000; /* in microseconds */
- private static native int halOpen();
- private static native int halTransmit(int halObject, int carrierFrequency, int[] pattern);
- private static native int[] halGetCarrierFrequencies(int halObject);
+ private static native long halOpen();
+ private static native int halTransmit(long halObject, int carrierFrequency, int[] pattern);
+ private static native int[] halGetCarrierFrequencies(long halObject);
private final Context mContext;
private final PowerManager.WakeLock mWakeLock;
- private final int mHal;
+ private final long mNativeHal;
private final Object mHalLock = new Object();
ConsumerIrService(Context context) {
@@ -65,23 +65,23 @@ public class ConsumerIrService extends IConsumerIrService.Stub {
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
mWakeLock.setReferenceCounted(true);
- mHal = halOpen();
+ mNativeHal = halOpen();
if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CONSUMER_IR)) {
- if (mHal == 0) {
+ if (mNativeHal == 0) {
throw new RuntimeException("FEATURE_CONSUMER_IR present, but no IR HAL loaded!");
}
- } else if (mHal != 0) {
+ } else if (mNativeHal != 0) {
throw new RuntimeException("IR HAL present, but FEATURE_CONSUMER_IR is not set!");
}
}
@Override
public boolean hasIrEmitter() {
- return mHal != 0;
+ return mNativeHal != 0;
}
private void throwIfNoIrEmitter() {
- if (mHal == 0) {
+ if (mNativeHal == 0) {
throw new UnsupportedOperationException("IR emitter not available");
}
}
@@ -111,7 +111,7 @@ public class ConsumerIrService extends IConsumerIrService.Stub {
// Right now there is no mechanism to ensure fair queing of IR requests
synchronized (mHalLock) {
- int err = halTransmit(mHal, carrierFrequency, pattern);
+ int err = halTransmit(mNativeHal, carrierFrequency, pattern);
if (err < 0) {
Slog.e(TAG, "Error transmitting: " + err);
@@ -129,7 +129,7 @@ public class ConsumerIrService extends IConsumerIrService.Stub {
throwIfNoIrEmitter();
synchronized(mHalLock) {
- return halGetCarrierFrequencies(mHal);
+ return halGetCarrierFrequencies(mNativeHal);
}
}
}
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index eebd1c5..e0b568b 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -452,6 +452,9 @@ public class LocationManagerService extends ILocationManager.Stub {
* @param userId the new active user's UserId
*/
private void switchUser(int userId) {
+ if (mCurrentUserId == userId) {
+ return;
+ }
mBlacklist.switchUser(userId);
mLocationHandler.removeMessages(MSG_LOCATION_CHANGED);
synchronized (mLock) {
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java
index 816ae69..f73a92b 100644
--- a/services/core/java/com/android/server/MountService.java
+++ b/services/core/java/com/android/server/MountService.java
@@ -91,6 +91,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -384,18 +385,37 @@ class MountService extends IMountService.Stub
}
class ShutdownCallBack extends UnmountCallBack {
- IMountShutdownObserver observer;
- ShutdownCallBack(String path, IMountShutdownObserver observer) {
+ MountShutdownLatch mMountShutdownLatch;
+ ShutdownCallBack(String path, final MountShutdownLatch mountShutdownLatch) {
super(path, true, false);
- this.observer = observer;
+ mMountShutdownLatch = mountShutdownLatch;
}
@Override
void handleFinished() {
int ret = doUnmountVolume(path, true, removeEncryption);
- if (observer != null) {
+ Slog.i(TAG, "Unmount completed: " + path + ", result code: " + ret);
+ mMountShutdownLatch.countDown();
+ }
+ }
+
+ static class MountShutdownLatch {
+ private IMountShutdownObserver mObserver;
+ private AtomicInteger mCount;
+
+ MountShutdownLatch(final IMountShutdownObserver observer, int count) {
+ mObserver = observer;
+ mCount = new AtomicInteger(count);
+ }
+
+ void countDown() {
+ boolean sendShutdown = false;
+ if (mCount.decrementAndGet() == 0) {
+ sendShutdown = true;
+ }
+ if (sendShutdown && mObserver != null) {
try {
- observer.onShutDownComplete(ret);
+ mObserver.onShutDownComplete(StorageResultCode.OperationSucceeded);
} catch (RemoteException e) {
Slog.w(TAG, "RemoteException when shutting down");
}
@@ -1426,6 +1446,10 @@ class MountService extends IMountService.Stub
Slog.i(TAG, "Shutting down");
synchronized (mVolumesLock) {
+ // Get all volumes to be unmounted.
+ MountShutdownLatch mountShutdownLatch = new MountShutdownLatch(observer,
+ mVolumeStates.size());
+
for (String path : mVolumeStates.keySet()) {
String state = mVolumeStates.get(path);
@@ -1461,19 +1485,16 @@ class MountService extends IMountService.Stub
if (state.equals(Environment.MEDIA_MOUNTED)) {
// Post a unmount message.
- ShutdownCallBack ucb = new ShutdownCallBack(path, observer);
+ ShutdownCallBack ucb = new ShutdownCallBack(path, mountShutdownLatch);
mHandler.sendMessage(mHandler.obtainMessage(H_UNMOUNT_PM_UPDATE, ucb));
} else if (observer != null) {
/*
- * Observer is waiting for onShutDownComplete when we are done.
- * Since nothing will be done send notification directly so shutdown
- * sequence can continue.
+ * Count down, since nothing will be done. The observer will be
+ * notified when we are done so shutdown sequence can continue.
*/
- try {
- observer.onShutDownComplete(StorageResultCode.OperationSucceeded);
- } catch (RemoteException e) {
- Slog.w(TAG, "RemoteException when shutting down");
- }
+ mountShutdownLatch.countDown();
+ Slog.i(TAG, "Unmount completed: " + path +
+ ", result code: " + StorageResultCode.OperationSucceeded);
}
}
}
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 71e7bac..e83d376 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -82,6 +82,7 @@ import java.net.SocketException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;
@@ -1022,6 +1023,15 @@ public class NetworkManagementService extends INetworkManagementService.Stub
}
}
+ private List<InterfaceAddress> excludeLinkLocal(List<InterfaceAddress> addresses) {
+ ArrayList<InterfaceAddress> filtered = new ArrayList<InterfaceAddress>(addresses.size());
+ for (InterfaceAddress ia : addresses) {
+ if (!ia.getAddress().isLinkLocalAddress())
+ filtered.add(ia);
+ }
+ return filtered;
+ }
+
private void modifyNat(String action, String internalInterface, String externalInterface)
throws SocketException {
final Command cmd = new Command("nat", action, internalInterface, externalInterface);
@@ -1031,8 +1041,10 @@ public class NetworkManagementService extends INetworkManagementService.Stub
if (internalNetworkInterface == null) {
cmd.appendArg("0");
} else {
- Collection<InterfaceAddress> interfaceAddresses = internalNetworkInterface
- .getInterfaceAddresses();
+ // Don't touch link-local routes, as link-local addresses aren't routable,
+ // kernel creates link-local routes on all interfaces automatically
+ List<InterfaceAddress> interfaceAddresses = excludeLinkLocal(
+ internalNetworkInterface.getInterfaceAddresses());
cmd.appendArg(interfaceAddresses.size());
for (InterfaceAddress ia : interfaceAddresses) {
InetAddress addr = NetworkUtils.getNetworkPart(
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 699d79e..77f5182 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -37,6 +37,10 @@ import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.CellInfo;
import android.telephony.TelephonyManager;
+import android.telephony.DisconnectCause;
+import android.telephony.PreciseCallState;
+import android.telephony.PreciseDataConnectionState;
+import android.telephony.PreciseDisconnectCause;
import android.text.TextUtils;
import android.util.Slog;
@@ -125,6 +129,17 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
private List<CellInfo> mCellInfo = null;
+ private int mRingingCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE;
+
+ private int mForegroundCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE;
+
+ private int mBackgroundCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE;
+
+ private PreciseCallState mPreciseCallState = new PreciseCallState();
+
+ private PreciseDataConnectionState mPreciseDataConnectionState =
+ new PreciseDataConnectionState();
+
static final int PHONE_STATE_PERMISSION_MASK =
PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR |
PhoneStateListener.LISTEN_CALL_STATE |
@@ -132,6 +147,10 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
PhoneStateListener.LISTEN_DATA_CONNECTION_STATE |
PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR;
+ static final int PRECISE_PHONE_STATE_PERMISSION_MASK =
+ PhoneStateListener.LISTEN_PRECISE_CALL_STATE |
+ PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE;
+
private static final int MSG_USER_SWITCHED = 1;
private final Handler mHandler = new Handler() {
@@ -305,6 +324,21 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
remove(r.binder);
}
}
+ if ((events & PhoneStateListener.LISTEN_PRECISE_CALL_STATE) != 0) {
+ try {
+ r.callback.onPreciseCallStateChanged(mPreciseCallState);
+ } catch (RemoteException ex) {
+ remove(r.binder);
+ }
+ }
+ if ((events & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) {
+ try {
+ r.callback.onPreciseDataConnectionStateChanged(
+ mPreciseDataConnectionState);
+ } catch (RemoteException ex) {
+ remove(r.binder);
+ }
+ }
}
}
} else {
@@ -533,30 +567,47 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
handleRemoveListLocked();
}
+ mPreciseDataConnectionState = new PreciseDataConnectionState(state, networkType,
+ apnType, apn, reason, linkProperties, "");
+ for (Record r : mRecords) {
+ if ((r.events & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) {
+ try {
+ r.callback.onPreciseDataConnectionStateChanged(mPreciseDataConnectionState);
+ } catch (RemoteException ex) {
+ mRemoveList.add(r.binder);
+ }
+ }
+ }
+ handleRemoveListLocked();
}
broadcastDataConnectionStateChanged(state, isDataConnectivityPossible, reason, apn,
apnType, linkProperties, linkCapabilities, roaming);
+ broadcastPreciseDataConnectionStateChanged(state, networkType, apnType, apn, reason,
+ linkProperties, "");
}
public void notifyDataConnectionFailed(String reason, String apnType) {
if (!checkNotifyPermission("notifyDataConnectionFailed()")) {
return;
}
- /*
- * This is commented out because there is no onDataConnectionFailed callback
- * in PhoneStateListener. There should be.
synchronized (mRecords) {
- mDataConnectionFailedReason = reason;
- final int N = mRecords.size();
- for (int i=N-1; i>=0; i--) {
- Record r = mRecords.get(i);
- if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_FAILED) != 0) {
- // XXX
+ mPreciseDataConnectionState = new PreciseDataConnectionState(
+ TelephonyManager.DATA_UNKNOWN,TelephonyManager.NETWORK_TYPE_UNKNOWN,
+ apnType, "", reason, null, "");
+ for (Record r : mRecords) {
+ if ((r.events & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) {
+ try {
+ r.callback.onPreciseDataConnectionStateChanged(mPreciseDataConnectionState);
+ } catch (RemoteException ex) {
+ mRemoveList.add(r.binder);
+ }
}
}
+ handleRemoveListLocked();
}
- */
broadcastDataConnectionFailed(reason, apnType);
+ broadcastPreciseDataConnectionStateChanged(TelephonyManager.DATA_UNKNOWN,
+ TelephonyManager.NETWORK_TYPE_UNKNOWN, apnType, "", reason, null, "");
}
public void notifyCellLocation(Bundle cellLocation) {
@@ -602,6 +653,81 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
}
+ public void notifyPreciseCallState(int ringingCallState, int foregroundCallState,
+ int backgroundCallState) {
+ if (!checkNotifyPermission("notifyPreciseCallState()")) {
+ return;
+ }
+ synchronized (mRecords) {
+ mRingingCallState = ringingCallState;
+ mForegroundCallState = foregroundCallState;
+ mBackgroundCallState = backgroundCallState;
+ mPreciseCallState = new PreciseCallState(ringingCallState, foregroundCallState,
+ backgroundCallState,
+ DisconnectCause.NOT_VALID,
+ PreciseDisconnectCause.NOT_VALID);
+ for (Record r : mRecords) {
+ if ((r.events & PhoneStateListener.LISTEN_PRECISE_CALL_STATE) != 0) {
+ try {
+ r.callback.onPreciseCallStateChanged(mPreciseCallState);
+ } catch (RemoteException ex) {
+ mRemoveList.add(r.binder);
+ }
+ }
+ }
+ handleRemoveListLocked();
+ }
+ broadcastPreciseCallStateChanged(ringingCallState, foregroundCallState, backgroundCallState,
+ DisconnectCause.NOT_VALID,
+ PreciseDisconnectCause.NOT_VALID);
+ }
+
+ public void notifyDisconnectCause(int disconnectCause, int preciseDisconnectCause) {
+ if (!checkNotifyPermission("notifyDisconnectCause()")) {
+ return;
+ }
+ synchronized (mRecords) {
+ mPreciseCallState = new PreciseCallState(mRingingCallState, mForegroundCallState,
+ mBackgroundCallState, disconnectCause, preciseDisconnectCause);
+ for (Record r : mRecords) {
+ if ((r.events & PhoneStateListener.LISTEN_PRECISE_CALL_STATE) != 0) {
+ try {
+ r.callback.onPreciseCallStateChanged(mPreciseCallState);
+ } catch (RemoteException ex) {
+ mRemoveList.add(r.binder);
+ }
+ }
+ }
+ handleRemoveListLocked();
+ }
+ broadcastPreciseCallStateChanged(mRingingCallState, mForegroundCallState,
+ mBackgroundCallState, disconnectCause, preciseDisconnectCause);
+ }
+
+ public void notifyPreciseDataConnectionFailed(String reason, String apnType,
+ String apn, String failCause) {
+ if (!checkNotifyPermission("notifyPreciseDataConnectionFailed()")) {
+ return;
+ }
+ synchronized (mRecords) {
+ mPreciseDataConnectionState = new PreciseDataConnectionState(
+ TelephonyManager.DATA_UNKNOWN, TelephonyManager.NETWORK_TYPE_UNKNOWN,
+ apnType, apn, reason, null, failCause);
+ for (Record r : mRecords) {
+ if ((r.events & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) {
+ try {
+ r.callback.onPreciseDataConnectionStateChanged(mPreciseDataConnectionState);
+ } catch (RemoteException ex) {
+ mRemoveList.add(r.binder);
+ }
+ }
+ }
+ handleRemoveListLocked();
+ }
+ broadcastPreciseDataConnectionStateChanged(TelephonyManager.DATA_UNKNOWN,
+ TelephonyManager.NETWORK_TYPE_UNKNOWN, apnType, apn, reason, null, failCause);
+ }
+
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
@@ -738,6 +864,33 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
}
+ private void broadcastPreciseCallStateChanged(int ringingCallState, int foregroundCallState,
+ int backgroundCallState, int disconnectCause, int preciseDisconnectCause) {
+ Intent intent = new Intent(TelephonyManager.ACTION_PRECISE_CALL_STATE_CHANGED);
+ intent.putExtra(TelephonyManager.EXTRA_RINGING_CALL_STATE, ringingCallState);
+ intent.putExtra(TelephonyManager.EXTRA_FOREGROUND_CALL_STATE, foregroundCallState);
+ intent.putExtra(TelephonyManager.EXTRA_BACKGROUND_CALL_STATE, backgroundCallState);
+ intent.putExtra(TelephonyManager.EXTRA_DISCONNECT_CAUSE, disconnectCause);
+ intent.putExtra(TelephonyManager.EXTRA_PRECISE_DISCONNECT_CAUSE, preciseDisconnectCause);
+ mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
+ android.Manifest.permission.READ_PRECISE_PHONE_STATE);
+ }
+
+ private void broadcastPreciseDataConnectionStateChanged(int state, int networkType,
+ String apnType, String apn, String reason, LinkProperties linkProperties, String failCause) {
+ Intent intent = new Intent(TelephonyManager.ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED);
+ intent.putExtra(PhoneConstants.STATE_KEY, state);
+ intent.putExtra(PhoneConstants.DATA_NETWORK_TYPE_KEY, networkType);
+ if (reason != null) intent.putExtra(PhoneConstants.STATE_CHANGE_REASON_KEY, reason);
+ if (apnType != null) intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType);
+ if (apn != null) intent.putExtra(PhoneConstants.DATA_APN_KEY, apn);
+ if (linkProperties != null) intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY, linkProperties);
+ if (failCause != null) intent.putExtra(PhoneConstants.DATA_FAILURE_CAUSE_KEY, failCause);
+
+ mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
+ android.Manifest.permission.READ_PRECISE_PHONE_STATE);
+ }
+
private boolean checkNotifyPermission(String method) {
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
== PackageManager.PERMISSION_GRANTED) {
@@ -766,6 +919,12 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.READ_PHONE_STATE, null);
}
+
+ if ((events & PRECISE_PHONE_STATE_PERMISSION_MASK) != 0) {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.READ_PRECISE_PHONE_STATE, null);
+
+ }
}
private void handleRemoveListLocked() {
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 17bb3e0..d66c5a7 100644..100755
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -203,6 +203,7 @@ public final class ActiveServices {
Slog.i(TAG, "Waited long enough for: " + r);
mStartingBackground.remove(i);
N--;
+ i--;
}
}
while (mDelayedStartList.size() > 0
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index d09ee96..8650647 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -42,6 +42,7 @@ import com.android.internal.os.BackgroundThread;
import com.android.internal.os.BatteryStatsImpl;
import com.android.internal.os.ProcessCpuTracker;
import com.android.internal.os.TransferPipe;
+import com.android.internal.os.Zygote;
import com.android.internal.util.FastPrintWriter;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.MemInfoReader;
@@ -61,7 +62,6 @@ import com.android.server.wm.WindowManagerService;
import com.google.android.collect.Lists;
import com.google.android.collect.Maps;
-import dalvik.system.Zygote;
import libcore.io.IoUtils;
import org.xmlpull.v1.XmlPullParser;
@@ -930,6 +930,11 @@ public final class ActivityManagerService extends ActivityManagerNative
*/
boolean mDidDexOpt;
+ /**
+ * Set if the systemServer made a call to enterSafeMode.
+ */
+ boolean mSafeMode;
+
String mDebugApp = null;
boolean mWaitForDebugger = false;
boolean mDebugTransient = false;
@@ -1058,6 +1063,7 @@ public final class ActivityManagerService extends ActivityManagerNative
static final int IMMERSIVE_MODE_LOCK_MSG = 37;
static final int PERSIST_URI_GRANTS_MSG = 38;
static final int REQUEST_ALL_PSS_MSG = 39;
+ static final int UPDATE_TIME = 40;
static final int FIRST_ACTIVITY_STACK_MSG = 100;
static final int FIRST_BROADCAST_QUEUE_MSG = 200;
@@ -1671,6 +1677,22 @@ public final class ActivityManagerService extends ActivityManagerNative
requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
break;
}
+ case UPDATE_TIME: {
+ synchronized (ActivityManagerService.this) {
+ for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
+ ProcessRecord r = mLruProcesses.get(i);
+ if (r.thread != null) {
+ try {
+ r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
+ } catch (RemoteException ex) {
+ Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
+ }
+ }
+ }
+ }
+
+ break;
+ }
}
}
};
@@ -2703,7 +2725,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// Run the app in safe mode if its manifest requests so or the
// system is booted in safe mode.
if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
- Zygote.systemInSafeMode == true) {
+ mSafeMode == true) {
debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
}
if ("1".equals(SystemProperties.get("debug.checkjni"))) {
@@ -2716,11 +2738,16 @@ public final class ActivityManagerService extends ActivityManagerNative
debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
}
+ String requiredAbi = app.info.requiredCpuAbi;
+ if (requiredAbi == null) {
+ requiredAbi = Build.SUPPORTED_ABIS[0];
+ }
+
// Start the process. It will either succeed and return a result containing
// the PID of the new process, or else throw a RuntimeException.
Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
app.processName, uid, uid, gids, debugFlags, mountExternal,
- app.info.targetSdkVersion, app.info.seinfo, null);
+ app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
synchronized (bs) {
@@ -8702,6 +8729,8 @@ public final class ActivityManagerService extends ActivityManagerNative
} catch (RemoteException e) {
}
}
+
+ mSafeMode = true;
}
}
@@ -12305,6 +12334,7 @@ public final class ActivityManagerService extends ActivityManagerNative
app.foregroundActivities = false;
app.hasShownUi = false;
app.hasAboveClient = false;
+ app.hasClientActivities = false;
mServices.killServicesLocked(app, allowRestart);
@@ -13317,11 +13347,20 @@ public final class ActivityManagerService extends ActivityManagerNative
* of all currently running processes. This message will get queued up before the broadcast
* happens.
*/
- if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
+ if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
}
- if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
+ /*
+ * If the user set the time, let all running processes know.
+ */
+ if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
+ final int is24Hour = intent.getBooleanExtra(
+ Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
+ mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
+ }
+
+ if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
}
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 5a9e690..37ead27 100644..100755
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -947,8 +947,8 @@ final class ActivityRecord {
// for another app to start, then we have paused dispatching
// for this activity.
ActivityRecord r = this;
- final ActivityStack stack = task.stack;
if (r.waitingVisible) {
+ final ActivityStack stack = mStackSupervisor.getFocusedStack();
// Hmmm, who might we be waiting for?
r = stack.mResumedActivity;
if (r == null) {
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index e4b196e..c6cd312 100755
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -1162,6 +1162,7 @@ final class ActivityStack {
// At this point, nothing else needs to be shown
if (DEBUG_VISBILITY) Slog.v(TAG, "Fullscreen: at " + r);
behindFullscreen = true;
+ showHomeBehindStack = false;
} else if (isActivityOverHome(r)) {
if (DEBUG_VISBILITY) Slog.v(TAG, "Showing home: at " + r);
showHomeBehindStack = true;
@@ -2662,6 +2663,9 @@ final class ActivityStack {
if (mResumedActivity == r) {
mResumedActivity = null;
}
+ if (mPausingActivity == r) {
+ mPausingActivity = null;
+ }
if (mService.mFocusedActivity == r) {
mService.mFocusedActivity = null;
}
diff --git a/services/core/java/com/android/server/am/CoreSettingsObserver.java b/services/core/java/com/android/server/am/CoreSettingsObserver.java
index 10ea67c..4c887dd 100644
--- a/services/core/java/com/android/server/am/CoreSettingsObserver.java
+++ b/services/core/java/com/android/server/am/CoreSettingsObserver.java
@@ -37,11 +37,16 @@ final class CoreSettingsObserver extends ContentObserver {
private static final String LOG_TAG = CoreSettingsObserver.class.getSimpleName();
// mapping form property name to its type
- private static final Map<String, Class<?>> sCoreSettingToTypeMap = new HashMap<
+ private static final Map<String, Class<?>> sSecureSettingToTypeMap = new HashMap<
+ String, Class<?>>();
+ private static final Map<String, Class<?>> sSystemSettingToTypeMap = new HashMap<
String, Class<?>>();
static {
- sCoreSettingToTypeMap.put(Settings.Secure.LONG_PRESS_TIMEOUT, int.class);
- // add other core settings here...
+ sSecureSettingToTypeMap.put(Settings.Secure.LONG_PRESS_TIMEOUT, int.class);
+ // add other secure settings here...
+
+ sSystemSettingToTypeMap.put(Settings.System.TIME_12_24, String.class);
+ // add other system settings here...
}
private final Bundle mCoreSettings = new Bundle();
@@ -67,39 +72,62 @@ final class CoreSettingsObserver extends ContentObserver {
}
private void sendCoreSettings() {
- populateCoreSettings(mCoreSettings);
+ populateSettings(mCoreSettings, sSecureSettingToTypeMap);
+ populateSettings(mCoreSettings, sSystemSettingToTypeMap);
mActivityManagerService.onCoreSettingsChange(mCoreSettings);
}
private void beginObserveCoreSettings() {
- for (String setting : sCoreSettingToTypeMap.keySet()) {
+ for (String setting : sSecureSettingToTypeMap.keySet()) {
Uri uri = Settings.Secure.getUriFor(setting);
mActivityManagerService.mContext.getContentResolver().registerContentObserver(
uri, false, this);
}
+
+ for (String setting : sSystemSettingToTypeMap.keySet()) {
+ Uri uri = Settings.System.getUriFor(setting);
+ mActivityManagerService.mContext.getContentResolver().registerContentObserver(
+ uri, false, this);
+ }
}
- private void populateCoreSettings(Bundle snapshot) {
+ private void populateSettings(Bundle snapshot, Map<String, Class<?>> map) {
Context context = mActivityManagerService.mContext;
- for (Map.Entry<String, Class<?>> entry : sCoreSettingToTypeMap.entrySet()) {
+ for (Map.Entry<String, Class<?>> entry : map.entrySet()) {
String setting = entry.getKey();
Class<?> type = entry.getValue();
try {
if (type == String.class) {
- String value = Settings.Secure.getString(context.getContentResolver(),
- setting);
+ final String value;
+ if (map == sSecureSettingToTypeMap) {
+ value = Settings.Secure.getString(context.getContentResolver(), setting);
+ } else {
+ value = Settings.System.getString(context.getContentResolver(), setting);
+ }
snapshot.putString(setting, value);
} else if (type == int.class) {
- int value = Settings.Secure.getInt(context.getContentResolver(),
- setting);
+ final int value;
+ if (map == sSecureSettingToTypeMap) {
+ value = Settings.Secure.getInt(context.getContentResolver(), setting);
+ } else {
+ value = Settings.System.getInt(context.getContentResolver(), setting);
+ }
snapshot.putInt(setting, value);
} else if (type == float.class) {
- float value = Settings.Secure.getFloat(context.getContentResolver(),
- setting);
+ final float value;
+ if (map == sSecureSettingToTypeMap) {
+ value = Settings.Secure.getFloat(context.getContentResolver(), setting);
+ } else {
+ value = Settings.System.getFloat(context.getContentResolver(), setting);
+ }
snapshot.putFloat(setting, value);
} else if (type == long.class) {
- long value = Settings.Secure.getLong(context.getContentResolver(),
- setting);
+ final long value;
+ if (map == sSecureSettingToTypeMap) {
+ value = Settings.Secure.getLong(context.getContentResolver(), setting);
+ } else {
+ value = Settings.System.getLong(context.getContentResolver(), setting);
+ }
snapshot.putLong(setting, value);
}
} catch (SettingNotFoundException snfe) {
diff --git a/services/core/java/com/android/server/am/NativeCrashListener.java b/services/core/java/com/android/server/am/NativeCrashListener.java
index b12843b..d42d415 100644
--- a/services/core/java/com/android/server/am/NativeCrashListener.java
+++ b/services/core/java/com/android/server/am/NativeCrashListener.java
@@ -17,18 +17,18 @@
package com.android.server.am;
import android.app.ApplicationErrorReport.CrashInfo;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.StructTimeval;
+import android.system.StructUcred;
import android.util.Slog;
-import libcore.io.ErrnoException;
-import libcore.io.Libcore;
-import libcore.io.StructTimeval;
-import libcore.io.StructUcred;
-
-import static libcore.io.OsConstants.*;
+import static android.system.OsConstants.*;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileDescriptor;
+import java.io.InterruptedIOException;
import java.net.InetSocketAddress;
import java.net.InetUnixAddress;
@@ -76,7 +76,7 @@ final class NativeCrashListener extends Thread {
try {
CrashInfo ci = new CrashInfo();
ci.exceptionClassName = "Native crash";
- ci.exceptionMessage = Libcore.os.strsignal(mSignal);
+ ci.exceptionMessage = Os.strsignal(mSignal);
ci.throwFileName = "unknown";
ci.throwClassName = "unknown";
ci.throwMethodName = "unknown";
@@ -116,22 +116,22 @@ final class NativeCrashListener extends Thread {
}
try {
- FileDescriptor serverFd = Libcore.os.socket(AF_UNIX, SOCK_STREAM, 0);
+ FileDescriptor serverFd = Os.socket(AF_UNIX, SOCK_STREAM, 0);
final InetUnixAddress sockAddr = new InetUnixAddress(DEBUGGERD_SOCKET_PATH);
- Libcore.os.bind(serverFd, sockAddr, 0);
- Libcore.os.listen(serverFd, 1);
+ Os.bind(serverFd, sockAddr, 0);
+ Os.listen(serverFd, 1);
while (true) {
InetSocketAddress peer = new InetSocketAddress();
FileDescriptor peerFd = null;
try {
if (MORE_DEBUG) Slog.v(TAG, "Waiting for debuggerd connection");
- peerFd = Libcore.os.accept(serverFd, peer);
+ peerFd = Os.accept(serverFd, peer);
if (MORE_DEBUG) Slog.v(TAG, "Got debuggerd socket " + peerFd);
if (peerFd != null) {
// Only the superuser is allowed to talk to us over this socket
StructUcred credentials =
- Libcore.os.getsockoptUcred(peerFd, SOL_SOCKET, SO_PEERCRED);
+ Os.getsockoptUcred(peerFd, SOL_SOCKET, SO_PEERCRED);
if (credentials.uid == 0) {
// the reporting thread may take responsibility for
// acking the debugger; make sure we play along.
@@ -145,7 +145,7 @@ final class NativeCrashListener extends Thread {
// byte written is irrelevant.
if (peerFd != null) {
try {
- Libcore.os.write(peerFd, ackSignal, 0, 1);
+ Os.write(peerFd, ackSignal, 0, 1);
} catch (Exception e) {
/* we don't care about failures here */
if (MORE_DEBUG) {
@@ -153,7 +153,7 @@ final class NativeCrashListener extends Thread {
}
}
try {
- Libcore.os.close(peerFd);
+ Os.close(peerFd);
} catch (ErrnoException e) {
if (MORE_DEBUG) {
Slog.d(TAG, "Exception closing socket: " + e.getMessage());
@@ -178,10 +178,10 @@ final class NativeCrashListener extends Thread {
}
static int readExactly(FileDescriptor fd, byte[] buffer, int offset, int numBytes)
- throws ErrnoException {
+ throws ErrnoException, InterruptedIOException {
int totalRead = 0;
while (numBytes > 0) {
- int n = Libcore.os.read(fd, buffer, offset + totalRead, numBytes);
+ int n = Os.read(fd, buffer, offset + totalRead, numBytes);
if (n <= 0) {
if (DEBUG) {
Slog.w(TAG, "Needed " + numBytes + " but saw " + n);
@@ -202,8 +202,8 @@ final class NativeCrashListener extends Thread {
try {
StructTimeval timeout = StructTimeval.fromMillis(SOCKET_TIMEOUT_MILLIS);
- Libcore.os.setsockoptTimeval(fd, SOL_SOCKET, SO_RCVTIMEO, timeout);
- Libcore.os.setsockoptTimeval(fd, SOL_SOCKET, SO_SNDTIMEO, timeout);
+ Os.setsockoptTimeval(fd, SOL_SOCKET, SO_RCVTIMEO, timeout);
+ Os.setsockoptTimeval(fd, SOL_SOCKET, SO_SNDTIMEO, timeout);
// first, the pid and signal number
int headerBytes = readExactly(fd, buf, 0, 8);
@@ -237,7 +237,7 @@ final class NativeCrashListener extends Thread {
int bytes;
do {
// get some data
- bytes = Libcore.os.read(fd, buf, 0, buf.length);
+ bytes = Os.read(fd, buf, 0, buf.length);
if (bytes > 0) {
if (MORE_DEBUG) {
String s = new String(buf, 0, bytes, "UTF-8");
diff --git a/services/core/java/com/android/server/am/UsageStatsService.java b/services/core/java/com/android/server/am/UsageStatsService.java
index 09cb344..5305c8f 100644
--- a/services/core/java/com/android/server/am/UsageStatsService.java
+++ b/services/core/java/com/android/server/am/UsageStatsService.java
@@ -75,42 +75,44 @@ public final class UsageStatsService extends IUsageStats.Stub {
private static final boolean localLOGV = false;
private static final boolean REPORT_UNEXPECTED = false;
private static final String TAG = "UsageStats";
-
+
// Current on-disk Parcel version
private static final int VERSION = 1008;
private static final int CHECKIN_VERSION = 4;
-
+
private static final String FILE_PREFIX = "usage-";
private static final String FILE_HISTORY = FILE_PREFIX + "history.xml";
- private static final int FILE_WRITE_INTERVAL = 30*60*1000; //ms
-
+ private static final int FILE_WRITE_INTERVAL = (localLOGV) ? 0 : 30*60*1000; // 30m in ms
+
private static final int MAX_NUM_FILES = 5;
-
+
private static final int NUM_LAUNCH_TIME_BINS = 10;
private static final int[] LAUNCH_TIME_BINS = {
250, 500, 750, 1000, 1500, 2000, 3000, 4000, 5000
};
-
+
static IUsageStats sService;
private Context mContext;
// structure used to maintain statistics since the last checkin.
- final private ArrayMap<String, PkgUsageStatsExtended> mStats;
+ final private ArrayMap<String, PkgUsageStatsExtended> mStats
+ = new ArrayMap<String, PkgUsageStatsExtended>();
// Maintains the last time any component was resumed, for all time.
- final private ArrayMap<String, ArrayMap<String, Long>> mLastResumeTimes;
+ final private ArrayMap<String, ArrayMap<String, Long>> mLastResumeTimes
+ = new ArrayMap<String, ArrayMap<String, Long>>();
// To remove last-resume time stats when a pacakge is removed.
private PackageMonitor mPackageMonitor;
// Lock to update package stats. Methods suffixed by SLOCK should invoked with
// this lock held
- final Object mStatsLock;
+ final Object mStatsLock = new Object();
// Lock to write to file. Methods suffixed by FLOCK should invoked with
// this lock held.
- final Object mFileLock;
+ final Object mFileLock = new Object();
// Order of locks is mFileLock followed by mStatsLock to avoid deadlocks
private String mLastResumedPkg;
private String mLastResumedComp;
@@ -120,52 +122,53 @@ public final class UsageStatsService extends IUsageStats.Stub {
private String mFileLeaf;
private File mDir;
- private Calendar mCal; // guarded by itself
+ private final Calendar mCal // guarded by itself
+ = Calendar.getInstance(TimeZone.getTimeZone("GMT+0"));
private final AtomicInteger mLastWriteDay = new AtomicInteger(-1);
private final AtomicLong mLastWriteElapsedTime = new AtomicLong(0);
private final AtomicBoolean mUnforcedDiskWriteRunning = new AtomicBoolean(false);
-
+
static class TimeStats {
- int count;
- int[] times = new int[NUM_LAUNCH_TIME_BINS];
-
+ int mCount;
+ final int[] mTimes = new int[NUM_LAUNCH_TIME_BINS];
+
TimeStats() {
}
-
+
void incCount() {
- count++;
+ mCount++;
}
-
+
void add(int val) {
final int[] bins = LAUNCH_TIME_BINS;
for (int i=0; i<NUM_LAUNCH_TIME_BINS-1; i++) {
if (val < bins[i]) {
- times[i]++;
+ mTimes[i]++;
return;
}
}
- times[NUM_LAUNCH_TIME_BINS-1]++;
+ mTimes[NUM_LAUNCH_TIME_BINS-1]++;
}
-
+
TimeStats(Parcel in) {
- count = in.readInt();
- final int[] localTimes = times;
+ mCount = in.readInt();
+ final int[] localTimes = mTimes;
for (int i=0; i<NUM_LAUNCH_TIME_BINS; i++) {
localTimes[i] = in.readInt();
}
}
-
+
void writeToParcel(Parcel out) {
- out.writeInt(count);
- final int[] localTimes = times;
+ out.writeInt(mCount);
+ final int[] localTimes = mTimes;
for (int i=0; i<NUM_LAUNCH_TIME_BINS; i++) {
out.writeInt(localTimes[i]);
}
}
}
-
- private class PkgUsageStatsExtended {
+
+ static class PkgUsageStatsExtended {
final ArrayMap<String, TimeStats> mLaunchTimes
= new ArrayMap<String, TimeStats>();
final ArrayMap<String, TimeStats> mFullyDrawnTimes
@@ -174,18 +177,18 @@ public final class UsageStatsService extends IUsageStats.Stub {
long mUsageTime;
long mPausedTime;
long mResumedTime;
-
+
PkgUsageStatsExtended() {
mLaunchCount = 0;
mUsageTime = 0;
}
-
+
PkgUsageStatsExtended(Parcel in) {
mLaunchCount = in.readInt();
mUsageTime = in.readLong();
if (localLOGV) Slog.v(TAG, "Launch count: " + mLaunchCount
+ ", Usage time:" + mUsageTime);
-
+
final int numLaunchTimeStats = in.readInt();
if (localLOGV) Slog.v(TAG, "Reading launch times: " + numLaunchTimeStats);
mLaunchTimes.ensureCapacity(numLaunchTimeStats);
@@ -209,16 +212,16 @@ public final class UsageStatsService extends IUsageStats.Stub {
void updateResume(String comp, boolean launched) {
if (launched) {
- mLaunchCount ++;
+ mLaunchCount++;
}
mResumedTime = SystemClock.elapsedRealtime();
}
-
+
void updatePause() {
mPausedTime = SystemClock.elapsedRealtime();
mUsageTime += (mPausedTime - mResumedTime);
}
-
+
void addLaunchCount(String comp) {
TimeStats times = mLaunchTimes.get(comp);
if (times == null) {
@@ -227,7 +230,7 @@ public final class UsageStatsService extends IUsageStats.Stub {
}
times.incCount();
}
-
+
void addLaunchTime(String comp, int millis) {
TimeStats times = mLaunchTimes.get(comp);
if (times == null) {
@@ -262,7 +265,7 @@ public final class UsageStatsService extends IUsageStats.Stub {
mFullyDrawnTimes.valueAt(i).writeToParcel(out);
}
}
-
+
void clear() {
mLaunchTimes.clear();
mFullyDrawnTimes.clear();
@@ -270,32 +273,25 @@ public final class UsageStatsService extends IUsageStats.Stub {
mUsageTime = 0;
}
}
-
+
UsageStatsService(String dir) {
- mStats = new ArrayMap<String, PkgUsageStatsExtended>();
- mLastResumeTimes = new ArrayMap<String, ArrayMap<String, Long>>();
- mStatsLock = new Object();
- mFileLock = new Object();
+ if (localLOGV) Slog.v(TAG, "UsageStatsService: " + dir);
mDir = new File(dir);
- mCal = Calendar.getInstance(TimeZone.getTimeZone("GMT+0"));
-
mDir.mkdir();
-
- // Remove any old usage files from previous versions.
+
+ // Remove any old /data/system/usagestats.* files from previous versions.
File parentDir = mDir.getParentFile();
- String fList[] = parentDir.list();
- if (fList != null) {
+ String files[] = parentDir.list();
+ if (files != null) {
String prefix = mDir.getName() + ".";
- int i = fList.length;
- while (i > 0) {
- i--;
- if (fList[i].startsWith(prefix)) {
- Slog.i(TAG, "Deleting old usage file: " + fList[i]);
- (new File(parentDir, fList[i])).delete();
+ for (String file : files) {
+ if (file.startsWith(prefix)) {
+ Slog.i(TAG, "Deleting old usage file: " + file);
+ (new File(parentDir, file)).delete();
}
}
}
-
+
// Update current stats which are binned by date
mFileLeaf = getCurrentDateStr(FILE_PREFIX);
mFile = new File(mDir, mFileLeaf);
@@ -312,11 +308,11 @@ public final class UsageStatsService extends IUsageStats.Stub {
*/
private String getCurrentDateStr(String prefix) {
StringBuilder sb = new StringBuilder();
+ if (prefix != null) {
+ sb.append(prefix);
+ }
synchronized (mCal) {
mCal.setTimeInMillis(System.currentTimeMillis());
- if (prefix != null) {
- sb.append(prefix);
- }
sb.append(mCal.get(Calendar.YEAR));
int mm = mCal.get(Calendar.MONTH) - Calendar.JANUARY +1;
if (mm < 10) {
@@ -331,17 +327,20 @@ public final class UsageStatsService extends IUsageStats.Stub {
}
return sb.toString();
}
-
+
private Parcel getParcelForFile(File file) throws IOException {
FileInputStream stream = new FileInputStream(file);
- byte[] raw = readFully(stream);
- Parcel in = Parcel.obtain();
- in.unmarshall(raw, 0, raw.length);
- in.setDataPosition(0);
- stream.close();
- return in;
+ try {
+ byte[] raw = readFully(stream);
+ Parcel in = Parcel.obtain();
+ in.unmarshall(raw, 0, raw.length);
+ in.setDataPosition(0);
+ return in;
+ } finally {
+ stream.close();
+ }
}
-
+
private void readStatsFromFile() {
File newFile = mFile;
synchronized (mFileLock) {
@@ -358,12 +357,13 @@ public final class UsageStatsService extends IUsageStats.Stub {
}
}
}
-
+
private void readStatsFLOCK(File file) throws IOException {
Parcel in = getParcelForFile(file);
int vers = in.readInt();
- if (vers != VERSION) {
- Slog.w(TAG, "Usage stats version changed; dropping");
+ if (vers != VERSION) { // vers will be 0 if the parcel file was empty
+ Slog.w(TAG, "Usage stats version of " + file + " changed from " + vers + " to "
+ + VERSION + "; dropping");
return;
}
int N = in.readInt();
@@ -384,12 +384,12 @@ public final class UsageStatsService extends IUsageStats.Stub {
private void readHistoryStatsFromFile() {
synchronized (mFileLock) {
if (mHistoryFile.getBaseFile().exists()) {
- readHistoryStatsFLOCK(mHistoryFile);
+ readHistoryStatsFLOCK();
}
}
}
- private void readHistoryStatsFLOCK(AtomicFile file) {
+ private void readHistoryStatsFLOCK() {
FileInputStream fis = null;
try {
fis = mHistoryFile.openRead();
@@ -472,12 +472,12 @@ public final class UsageStatsService extends IUsageStats.Stub {
}
return fileList;
}
-
+
private void checkFileLimitFLOCK() {
// Get all usage stats output files
ArrayList<String> fileList = getUsageStatsFileListFLOCK();
if (fileList == null) {
- // Strange but we dont have to delete any thing
+ // Empty /data/system/usagestats/ so we don't have anything to delete
return;
}
int count = fileList.size();
@@ -577,8 +577,8 @@ public final class UsageStatsService extends IUsageStats.Stub {
}
if (dayChanged || forceWriteHistoryStats) {
- // Write history stats daily, or when forced (due to shutdown).
- writeHistoryStatsFLOCK(mHistoryFile);
+ // Write history stats daily or when forced (due to shutdown) or when debugging.
+ writeHistoryStatsFLOCK();
}
// Delete the backup file
@@ -640,10 +640,10 @@ public final class UsageStatsService extends IUsageStats.Stub {
}
}
- private void writeHistoryStatsFLOCK(AtomicFile historyFile) {
+ private void writeHistoryStatsFLOCK() {
FileOutputStream fos = null;
try {
- fos = historyFile.startWrite();
+ fos = mHistoryFile.startWrite();
XmlSerializer out = new FastXmlSerializer();
out.setOutput(fos, "utf-8");
out.startDocument(null, true);
@@ -666,11 +666,11 @@ public final class UsageStatsService extends IUsageStats.Stub {
out.endTag(null, "usage-history");
out.endDocument();
- historyFile.finishWrite(fos);
+ mHistoryFile.finishWrite(fos);
} catch (IOException e) {
Slog.w(TAG,"Error writing history stats" + e);
if (fos != null) {
- historyFile.failWrite(fos);
+ mHistoryFile.failWrite(fos);
}
}
}
@@ -713,7 +713,8 @@ public final class UsageStatsService extends IUsageStats.Stub {
sService = asInterface(b);
return sService;
}
-
+
+ @Override
public void noteResumeComponent(ComponentName componentName) {
enforceCallingPermission();
String pkgName;
@@ -722,7 +723,7 @@ public final class UsageStatsService extends IUsageStats.Stub {
((pkgName = componentName.getPackageName()) == null)) {
return;
}
-
+
final boolean samePackage = pkgName.equals(mLastResumedPkg);
if (mIsResumed) {
if (mLastResumedPkg != null) {
@@ -736,14 +737,14 @@ public final class UsageStatsService extends IUsageStats.Stub {
}
}
}
-
+
final boolean sameComp = samePackage
&& componentName.getClassName().equals(mLastResumedComp);
-
+
mIsResumed = true;
mLastResumedPkg = pkgName;
mLastResumedComp = componentName.getClassName();
-
+
if (localLOGV) Slog.i(TAG, "started component:" + pkgName);
PkgUsageStatsExtended pus = mStats.get(pkgName);
if (pus == null) {
@@ -764,9 +765,10 @@ public final class UsageStatsService extends IUsageStats.Stub {
}
}
+ @Override
public void notePauseComponent(ComponentName componentName) {
enforceCallingPermission();
-
+
synchronized (mStatsLock) {
String pkgName;
if ((componentName == null) ||
@@ -779,9 +781,9 @@ public final class UsageStatsService extends IUsageStats.Stub {
return;
}
mIsResumed = false;
-
+
if (localLOGV) Slog.i(TAG, "paused component:"+pkgName);
-
+
PkgUsageStatsExtended pus = mStats.get(pkgName);
if (pus == null) {
// Weird some error here
@@ -790,11 +792,12 @@ public final class UsageStatsService extends IUsageStats.Stub {
}
pus.updatePause();
}
-
+
// Persist current data to file if needed.
writeStatsToFile(false, false);
}
-
+
+ @Override
public void noteLaunchTime(ComponentName componentName, int millis) {
enforceCallingPermission();
String pkgName;
@@ -802,10 +805,10 @@ public final class UsageStatsService extends IUsageStats.Stub {
((pkgName = componentName.getPackageName()) == null)) {
return;
}
-
+
// Persist current data to file if needed.
writeStatsToFile(false, false);
-
+
synchronized (mStatsLock) {
PkgUsageStatsExtended pus = mStats.get(pkgName);
if (pus != null) {
@@ -813,7 +816,7 @@ public final class UsageStatsService extends IUsageStats.Stub {
}
}
}
-
+
public void noteFullyDrawnTime(ComponentName componentName, int millis) {
enforceCallingPermission();
String pkgName;
@@ -840,7 +843,8 @@ public final class UsageStatsService extends IUsageStats.Stub {
mContext.enforcePermission(android.Manifest.permission.UPDATE_DEVICE_STATS,
Binder.getCallingPid(), Binder.getCallingUid(), null);
}
-
+
+ @Override
public PkgUsageStats getPkgUsageStats(ComponentName componentName) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.PACKAGE_USAGE_STATS, null);
@@ -860,7 +864,8 @@ public final class UsageStatsService extends IUsageStats.Stub {
return new PkgUsageStats(pkgName, launchCount, usageTime, lastResumeTimes);
}
}
-
+
+ @Override
public PkgUsageStats[] getAllPkgUsageStats() {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.PACKAGE_USAGE_STATS, null);
@@ -886,8 +891,8 @@ public final class UsageStatsService extends IUsageStats.Stub {
return retArr;
}
}
-
- static byte[] readFully(FileInputStream stream) throws java.io.IOException {
+
+ static byte[] readFully(FileInputStream stream) throws IOException {
int pos = 0;
int avail = stream.available();
byte[] data = new byte[avail];
@@ -905,7 +910,7 @@ public final class UsageStatsService extends IUsageStats.Stub {
}
}
}
-
+
private void collectDumpInfoFLOCK(PrintWriter pw, boolean isCompactOutput,
boolean deleteAfterPrint, HashSet<String> packages) {
List<String> fileList = getUsageStatsFileListFLOCK();
@@ -934,15 +939,12 @@ public final class UsageStatsService extends IUsageStats.Stub {
// Delete old file after collecting info only for checkin requests
dFile.delete();
}
- } catch (FileNotFoundException e) {
- Slog.w(TAG, "Failed with "+e+" when collecting dump info from file : " + file);
- return;
} catch (IOException e) {
Slog.w(TAG, "Failed with "+e+" when collecting dump info from file : "+file);
- }
+ }
}
}
-
+
private void collectDumpInfoFromParcelFLOCK(Parcel in, PrintWriter pw,
String date, boolean isCompactOutput, HashSet<String> packages) {
StringBuilder sb = new StringBuilder(512);
@@ -953,19 +955,19 @@ public final class UsageStatsService extends IUsageStats.Stub {
} else {
sb.append("Date: ");
}
-
+
sb.append(date);
-
+
int vers = in.readInt();
if (vers != VERSION) {
sb.append(" (old data version)");
pw.println(sb.toString());
return;
}
-
+
pw.println(sb.toString());
int N = in.readInt();
-
+
while (N > 0) {
N--;
String pkgName = in.readString();
@@ -992,10 +994,10 @@ public final class UsageStatsService extends IUsageStats.Stub {
sb.append(activity);
TimeStats times = pus.mLaunchTimes.valueAt(i);
sb.append(',');
- sb.append(times.count);
+ sb.append(times.mCount);
for (int j=0; j<NUM_LAUNCH_TIME_BINS; j++) {
sb.append(",");
- sb.append(times.times[j]);
+ sb.append(times.mTimes[j]);
}
sb.append('\n');
}
@@ -1007,7 +1009,7 @@ public final class UsageStatsService extends IUsageStats.Stub {
TimeStats times = pus.mFullyDrawnTimes.valueAt(i);
for (int j=0; j<NUM_LAUNCH_TIME_BINS; j++) {
sb.append(",");
- sb.append(times.times[j]);
+ sb.append(times.mTimes[j]);
}
sb.append('\n');
}
@@ -1027,26 +1029,26 @@ public final class UsageStatsService extends IUsageStats.Stub {
sb.append(pus.mLaunchTimes.keyAt(i));
TimeStats times = pus.mLaunchTimes.valueAt(i);
sb.append(": ");
- sb.append(times.count);
+ sb.append(times.mCount);
sb.append(" starts");
int lastBin = 0;
for (int j=0; j<NUM_LAUNCH_TIME_BINS-1; j++) {
- if (times.times[j] != 0) {
+ if (times.mTimes[j] != 0) {
sb.append(", ");
sb.append(lastBin);
sb.append('-');
sb.append(LAUNCH_TIME_BINS[j]);
sb.append("ms=");
- sb.append(times.times[j]);
+ sb.append(times.mTimes[j]);
}
lastBin = LAUNCH_TIME_BINS[j];
}
- if (times.times[NUM_LAUNCH_TIME_BINS-1] != 0) {
+ if (times.mTimes[NUM_LAUNCH_TIME_BINS-1] != 0) {
sb.append(", ");
sb.append(">=");
sb.append(lastBin);
sb.append("ms=");
- sb.append(times.times[NUM_LAUNCH_TIME_BINS-1]);
+ sb.append(times.mTimes[NUM_LAUNCH_TIME_BINS-1]);
}
sb.append('\n');
}
@@ -1059,7 +1061,7 @@ public final class UsageStatsService extends IUsageStats.Stub {
boolean needComma = false;
int lastBin = 0;
for (int j=0; j<NUM_LAUNCH_TIME_BINS-1; j++) {
- if (times.times[j] != 0) {
+ if (times.mTimes[j] != 0) {
if (needComma) {
sb.append(", ");
} else {
@@ -1069,27 +1071,27 @@ public final class UsageStatsService extends IUsageStats.Stub {
sb.append('-');
sb.append(LAUNCH_TIME_BINS[j]);
sb.append("ms=");
- sb.append(times.times[j]);
+ sb.append(times.mTimes[j]);
}
lastBin = LAUNCH_TIME_BINS[j];
}
- if (times.times[NUM_LAUNCH_TIME_BINS-1] != 0) {
+ if (times.mTimes[NUM_LAUNCH_TIME_BINS-1] != 0) {
if (needComma) {
sb.append(", ");
}
sb.append(">=");
sb.append(lastBin);
sb.append("ms=");
- sb.append(times.times[NUM_LAUNCH_TIME_BINS-1]);
+ sb.append(times.mTimes[NUM_LAUNCH_TIME_BINS-1]);
}
sb.append('\n');
}
}
-
+
pw.write(sb.toString());
}
}
-
+
/**
* Searches array of arguments for the specified string
* @param args array of argument strings
@@ -1106,7 +1108,7 @@ public final class UsageStatsService extends IUsageStats.Stub {
}
return false;
}
-
+
/**
* Searches array of arguments for the specified string's data
* @param args array of argument strings
@@ -1125,11 +1127,11 @@ public final class UsageStatsService extends IUsageStats.Stub {
}
return null;
}
-
- @Override
+
/*
- * The data persisted to file is parsed and the stats are computed.
+ * The data persisted to file is parsed and the stats are computed.
*/
+ @Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (mContext.checkCallingPermission(android.Manifest.permission.DUMP)
!= PackageManager.PERMISSION_GRANTED) {
@@ -1143,23 +1145,23 @@ public final class UsageStatsService extends IUsageStats.Stub {
final boolean isCompactOutput = isCheckinRequest || scanArgs(args, "-c");
final boolean deleteAfterPrint = isCheckinRequest || scanArgs(args, "-d");
final String rawPackages = scanArgsData(args, "--packages");
-
+
// Make sure the current stats are written to the file. This
// doesn't need to be done if we are deleting files after printing,
- // since it that case we won't print the current stats.
+ // since in that case we won't print the current stats.
if (!deleteAfterPrint) {
writeStatsToFile(true, false);
}
-
+
HashSet<String> packages = null;
if (rawPackages != null) {
if (!"*".equals(rawPackages)) {
// A * is a wildcard to show all packages.
String[] names = rawPackages.split(",");
+ if (names.length != 0) {
+ packages = new HashSet<String>();
+ }
for (String n : names) {
- if (packages == null) {
- packages = new HashSet<String>();
- }
packages.add(n);
}
}
@@ -1169,7 +1171,7 @@ public final class UsageStatsService extends IUsageStats.Stub {
Slog.w(TAG, "Checkin without packages");
return;
}
-
+
synchronized (mFileLock) {
collectDumpInfoFLOCK(pw, isCompactOutput, deleteAfterPrint, packages);
}
diff --git a/services/core/java/com/android/server/firewall/IntentFirewall.java b/services/core/java/com/android/server/firewall/IntentFirewall.java
index 88a2207..eb7a383 100644
--- a/services/core/java/com/android/server/firewall/IntentFirewall.java
+++ b/services/core/java/com/android/server/firewall/IntentFirewall.java
@@ -270,11 +270,13 @@ public class IntentFirewall {
}
File[] files = rulesDir.listFiles();
- for (int i=0; i<files.length; i++) {
- File file = files[i];
+ if (files != null) {
+ for (int i=0; i<files.length; i++) {
+ File file = files[i];
- if (file.getName().endsWith(".xml")) {
- readRules(file, resolvers);
+ if (file.getName().endsWith(".xml")) {
+ readRules(file, resolvers);
+ }
}
}
diff --git a/services/core/java/com/android/server/lights/LightsService.java b/services/core/java/com/android/server/lights/LightsService.java
index 62c0ec9..94cf668 100644
--- a/services/core/java/com/android/server/lights/LightsService.java
+++ b/services/core/java/com/android/server/lights/LightsService.java
@@ -78,6 +78,7 @@ public class LightsService extends SystemService {
synchronized (this) {
if (mColor == 0 && !mFlashing) {
setLightLocked(color, LIGHT_FLASH_HARDWARE, onMS, 1000, BRIGHTNESS_MODE_USER);
+ mColor = 0;
mH.sendMessageDelayed(Message.obtain(mH, 1, this), onMS);
}
}
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index 6185e50..82d3f53 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -211,29 +211,62 @@ public final class Installer extends SystemService {
return execute(builder.toString());
}
- public int dexopt(String apkPath, int uid, boolean isPublic) {
+ public int dexopt(String apkPath, int uid, boolean isPublic, String instructionSet) {
StringBuilder builder = new StringBuilder("dexopt");
builder.append(' ');
builder.append(apkPath);
builder.append(' ');
builder.append(uid);
builder.append(isPublic ? " 1" : " 0");
+ builder.append(" *"); // No pkgName arg present
+ builder.append(' ');
+ builder.append(instructionSet);
+ return execute(builder.toString());
+ }
+
+ public int dexopt(String apkPath, int uid, boolean isPublic, String pkgName,
+ String instructionSet) {
+ StringBuilder builder = new StringBuilder("dexopt");
+ builder.append(' ');
+ builder.append(apkPath);
+ builder.append(' ');
+ builder.append(uid);
+ builder.append(isPublic ? " 1" : " 0");
+ builder.append(' ');
+ builder.append(pkgName);
+ builder.append(' ');
+ builder.append(instructionSet);
return execute(builder.toString());
}
- public int movedex(String srcPath, String dstPath) {
+ public int idmap(String targetApkPath, String overlayApkPath, int uid) {
+ StringBuilder builder = new StringBuilder("idmap");
+ builder.append(' ');
+ builder.append(targetApkPath);
+ builder.append(' ');
+ builder.append(overlayApkPath);
+ builder.append(' ');
+ builder.append(uid);
+ return execute(builder.toString());
+ }
+
+ public int movedex(String srcPath, String dstPath, String instructionSet) {
StringBuilder builder = new StringBuilder("movedex");
builder.append(' ');
builder.append(srcPath);
builder.append(' ');
builder.append(dstPath);
+ builder.append(' ');
+ builder.append(instructionSet);
return execute(builder.toString());
}
- public int rmdex(String codePath) {
+ public int rmdex(String codePath, String instructionSet) {
StringBuilder builder = new StringBuilder("rmdex");
builder.append(' ');
builder.append(codePath);
+ builder.append(' ');
+ builder.append(instructionSet);
return execute(builder.toString());
}
@@ -320,7 +353,7 @@ public final class Installer extends SystemService {
}
public int getSizeInfo(String pkgName, int persona, String apkPath, String libDirPath,
- String fwdLockApkPath, String asecPath, PackageStats pStats) {
+ String fwdLockApkPath, String asecPath, String instructionSet, PackageStats pStats) {
StringBuilder builder = new StringBuilder("getsize");
builder.append(' ');
builder.append(pkgName);
@@ -334,6 +367,8 @@ public final class Installer extends SystemService {
builder.append(fwdLockApkPath != null ? fwdLockApkPath : "!");
builder.append(' ');
builder.append(asecPath != null ? asecPath : "!");
+ builder.append(' ');
+ builder.append(instructionSet);
String s = transaction(builder.toString());
String res[] = s.split(" ");
@@ -382,4 +417,15 @@ public final class Installer extends SystemService {
return execute(builder.toString());
}
+
+ public boolean restoreconData(String pkgName, String seinfo, int uid) {
+ StringBuilder builder = new StringBuilder("restorecondata");
+ builder.append(' ');
+ builder.append(pkgName);
+ builder.append(' ');
+ builder.append(seinfo != null ? seinfo : "!");
+ builder.append(' ');
+ builder.append(uid);
+ return (execute(builder.toString()) == 0);
+ }
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 0f2bea6..b0428cb 100755
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -23,14 +23,15 @@ import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
+import static android.system.OsConstants.S_IRWXU;
+import static android.system.OsConstants.S_IRGRP;
+import static android.system.OsConstants.S_IXGRP;
+import static android.system.OsConstants.S_IROTH;
+import static android.system.OsConstants.S_IXOTH;
import static com.android.internal.util.ArrayUtils.appendInt;
import static com.android.internal.util.ArrayUtils.removeInt;
-import static libcore.io.OsConstants.S_IRWXU;
-import static libcore.io.OsConstants.S_IRGRP;
-import static libcore.io.OsConstants.S_IXGRP;
-import static libcore.io.OsConstants.S_IROTH;
-import static libcore.io.OsConstants.S_IXOTH;
+import android.content.pm.PackageParser.*;
import com.android.internal.app.IMediaContainerService;
import com.android.internal.app.ResolverActivity;
import com.android.internal.content.NativeLibraryHelper;
@@ -60,8 +61,8 @@ import android.content.IIntentReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentSender;
-import android.content.ServiceConnection;
import android.content.IntentSender.SendIntentException;
+import android.content.ServiceConnection;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.ContainerEncryptionParams;
@@ -73,14 +74,14 @@ import android.content.pm.IPackageManager;
import android.content.pm.IPackageMoveObserver;
import android.content.pm.IPackageStatsObserver;
import android.content.pm.InstrumentationInfo;
+import android.content.pm.ManifestDigest;
import android.content.pm.PackageCleanItem;
import android.content.pm.PackageInfo;
import android.content.pm.PackageInfoLite;
import android.content.pm.PackageManager;
import android.content.pm.PackageParser;
-import android.content.pm.PackageUserState;
-import android.content.pm.PackageParser.ActivityIntentInfo;
import android.content.pm.PackageStats;
+import android.content.pm.PackageUserState;
import android.content.pm.ParceledListSlice;
import android.content.pm.PermissionGroupInfo;
import android.content.pm.PermissionInfo;
@@ -88,7 +89,6 @@ import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.Signature;
-import android.content.pm.ManifestDigest;
import android.content.pm.VerificationParams;
import android.content.pm.VerifierDeviceIdentity;
import android.content.pm.VerifierInfo;
@@ -99,6 +99,7 @@ import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
+import android.os.Environment.UserEnvironment;
import android.os.FileObserver;
import android.os.FileUtils;
import android.os.Handler;
@@ -115,10 +116,12 @@ import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserHandle;
-import android.os.Environment.UserEnvironment;
import android.os.UserManager;
import android.security.KeyStore;
import android.security.SystemKeyStore;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.StructStat;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.EventLog;
@@ -157,10 +160,8 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
-import libcore.io.ErrnoException;
+import dalvik.system.VMRuntime;
import libcore.io.IoUtils;
-import libcore.io.Libcore;
-import libcore.io.StructStat;
import com.android.internal.R;
import com.android.server.storage.DeviceStorageMonitorInternal;
@@ -219,7 +220,8 @@ public class PackageManagerService extends IPackageManager.Stub {
static final int SCAN_UPDATE_TIME = 1<<6;
static final int SCAN_DEFER_DEX = 1<<7;
static final int SCAN_BOOTING = 1<<8;
- static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<9;
+ static final int SCAN_TRUSTED_OVERLAY = 1<<9;
+ static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10;
static final int REMOVE_CHATTY = 1<<16;
@@ -259,10 +261,19 @@ public class PackageManagerService extends IPackageManager.Stub {
private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
private static final String LIB_DIR_NAME = "lib";
+ private static final String LIB64_DIR_NAME = "lib64";
+
+ private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
static final String mTempContainerPrefix = "smdl2tmp";
final ServiceThread mHandlerThread;
+
+ private static String sPreferredInstructionSet;
+
+ private static final String IDMAP_PREFIX = "/data/resource-cache/";
+ private static final String IDMAP_SUFFIX = "@idmap";
+
final PackageHandler mHandler;
final int mSdkVersion = Build.VERSION.SDK_INT;
@@ -298,6 +309,9 @@ public class PackageManagerService extends IPackageManager.Stub {
// This is the object monitoring the system app dir.
final FileObserver mVendorInstallObserver;
+ // This is the object monitoring the vendor overlay package dir.
+ final FileObserver mVendorOverlayInstallObserver;
+
// This is the object monitoring mAppInstallDir.
final FileObserver mAppInstallObserver;
@@ -344,6 +358,10 @@ public class PackageManagerService extends IPackageManager.Stub {
final HashMap<String, PackageParser.Package> mPackages =
new HashMap<String, PackageParser.Package>();
+ // Tracks available target package names -> overlay package paths.
+ final HashMap<String, HashMap<String, PackageParser.Package>> mOverlays =
+ new HashMap<String, HashMap<String, PackageParser.Package>>();
+
final Settings mSettings;
boolean mRestoredSettings;
@@ -381,6 +399,9 @@ public class PackageManagerService extends IPackageManager.Stub {
// If mac_permissions.xml was found for seinfo labeling.
boolean mFoundPolicyFile;
+ // If a recursive restorecon of /data/data/<pkg> is needed.
+ private boolean mShouldRestoreconData = SELinuxMMAC.shouldRestorecon();
+
// All available activities, for your resolving pleasure.
final ActivityIntentResolver mActivities =
new ActivityIntentResolver();
@@ -1191,27 +1212,38 @@ public class PackageManagerService extends IPackageManager.Stub {
boolean didDexOpt = false;
+ final List<String> instructionSets = getAllInstructionSets();
+
/**
* Ensure all external libraries have had dexopt run on them.
*/
if (mSharedLibraries.size() > 0) {
- Iterator<SharedLibraryEntry> libs = mSharedLibraries.values().iterator();
- while (libs.hasNext()) {
- String lib = libs.next().path;
- if (lib == null) {
- continue;
- }
- try {
- if (dalvik.system.DexFile.isDexOptNeeded(lib)) {
- alreadyDexOpted.add(lib);
- mInstaller.dexopt(lib, Process.SYSTEM_UID, true);
- didDexOpt = true;
+ // NOTE: For now, we're compiling these system "shared libraries"
+ // (and framework jars) into all available architectures. It's possible
+ // to compile them only when we come across an app that uses them (there's
+ // already logic for that in scanPackageLI) but that adds some complexity.
+ for (String instructionSet : instructionSets) {
+ for (SharedLibraryEntry libEntry : mSharedLibraries.values()) {
+ final String lib = libEntry.path;
+ if (lib == null) {
+ continue;
+ }
+
+ try {
+ if (dalvik.system.DexFile.isDexOptNeededInternal(
+ lib, null, instructionSet, false)) {
+ alreadyDexOpted.add(lib);
+
+ // The list of "shared libraries" we have at this point is
+ mInstaller.dexopt(lib, Process.SYSTEM_UID, true, instructionSet);
+ didDexOpt = true;
+ }
+ } catch (FileNotFoundException e) {
+ Slog.w(TAG, "Library not found: " + lib);
+ } catch (IOException e) {
+ Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? "
+ + e.getMessage());
}
- } catch (FileNotFoundException e) {
- Slog.w(TAG, "Library not found: " + lib);
- } catch (IOException e) {
- Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? "
- + e.getMessage());
}
}
}
@@ -1234,51 +1266,50 @@ public class PackageManagerService extends IPackageManager.Stub {
*/
String[] frameworkFiles = frameworkDir.list();
if (frameworkFiles != null) {
- for (int i=0; i<frameworkFiles.length; i++) {
- File libPath = new File(frameworkDir, frameworkFiles[i]);
- String path = libPath.getPath();
- // Skip the file if we alrady did it.
- if (alreadyDexOpted.contains(path)) {
- continue;
- }
- // Skip the file if it is not a type we want to dexopt.
- if (!path.endsWith(".apk") && !path.endsWith(".jar")) {
- continue;
- }
- try {
- if (dalvik.system.DexFile.isDexOptNeeded(path)) {
- mInstaller.dexopt(path, Process.SYSTEM_UID, true);
- didDexOpt = true;
+ // TODO: We could compile these only for the most preferred ABI. We should
+ // first double check that the dex files for these commands are not referenced
+ // by other system apps.
+ for (String instructionSet : instructionSets) {
+ for (int i=0; i<frameworkFiles.length; i++) {
+ File libPath = new File(frameworkDir, frameworkFiles[i]);
+ String path = libPath.getPath();
+ // Skip the file if we already did it.
+ if (alreadyDexOpted.contains(path)) {
+ continue;
+ }
+ // Skip the file if it is not a type we want to dexopt.
+ if (!path.endsWith(".apk") && !path.endsWith(".jar")) {
+ continue;
+ }
+ try {
+ if (dalvik.system.DexFile.isDexOptNeededInternal(path, null, instructionSet, false)) {
+ mInstaller.dexopt(path, Process.SYSTEM_UID, true, instructionSet);
+ didDexOpt = true;
+ }
+ } catch (FileNotFoundException e) {
+ Slog.w(TAG, "Jar not found: " + path);
+ } catch (IOException e) {
+ Slog.w(TAG, "Exception reading jar: " + path, e);
}
- } catch (FileNotFoundException e) {
- Slog.w(TAG, "Jar not found: " + path);
- } catch (IOException e) {
- Slog.w(TAG, "Exception reading jar: " + path, e);
}
}
}
if (didDexOpt) {
- File dalvikCacheDir = new File(dataDir, "dalvik-cache");
-
- // If we had to do a dexopt of one of the previous
- // things, then something on the system has changed.
- // Consider this significant, and wipe away all other
- // existing dexopt files to ensure we don't leave any
- // dangling around.
- String[] files = dalvikCacheDir.list();
- if (files != null) {
- for (int i=0; i<files.length; i++) {
- String fn = files[i];
- if (fn.startsWith("data@app@")
- || fn.startsWith("data@app-private@")) {
- Slog.i(TAG, "Pruning dalvik file: " + fn);
- (new File(dalvikCacheDir, fn)).delete();
- }
- }
- }
+ pruneDexFiles(new File(dataDir, "dalvik-cache"));
}
+ // Collect vendor overlay packages.
+ // (Do this before scanning any apps.)
+ // For security and version matching reason, only consider
+ // overlay packages if they reside in VENDOR_OVERLAY_DIR.
+ File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR);
+ mVendorOverlayInstallObserver = new AppDirObserver(
+ vendorOverlayDir.getPath(), OBSERVER_EVENTS, true, false);
+ mVendorOverlayInstallObserver.startWatching();
+ scanDirLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM
+ | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode | SCAN_TRUSTED_OVERLAY, 0);
+
// Find base frameworks (resource packages without code).
mFrameworkInstallObserver = new AppDirObserver(
frameworkDir.getPath(), OBSERVER_EVENTS, true, false);
@@ -1307,6 +1338,11 @@ public class PackageManagerService extends IPackageManager.Stub {
// Collect all vendor packages.
File vendorAppDir = new File("/vendor/app");
+ try {
+ vendorAppDir = vendorAppDir.getCanonicalFile();
+ } catch (IOException e) {
+ // failed to look up canonical path, continue with original one
+ }
mVendorInstallObserver = new AppDirObserver(
vendorAppDir.getPath(), OBSERVER_EVENTS, true, false);
mVendorInstallObserver.startWatching();
@@ -1430,6 +1466,12 @@ public class PackageManagerService extends IPackageManager.Stub {
// the correct library paths.
updateAllSharedLibrariesLPw();
+
+ for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
+ adjustCpuAbisForSharedUserLPw(setting.packages, true /* do dexopt */,
+ false /* force dexopt */, false /* defer dexopt */);
+ }
+
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
SystemClock.uptimeMillis());
Slog.i(TAG, "Time to scan packages: "
@@ -1476,6 +1518,37 @@ public class PackageManagerService extends IPackageManager.Stub {
} // synchronized (mInstallLock)
}
+ private static void pruneDexFiles(File cacheDir) {
+ // If we had to do a dexopt of one of the previous
+ // things, then something on the system has changed.
+ // Consider this significant, and wipe away all other
+ // existing dexopt files to ensure we don't leave any
+ // dangling around.
+ //
+ // Additionally, delete all dex files from the root directory
+ // since there shouldn't be any there anyway.
+ File[] files = cacheDir.listFiles();
+ if (files != null) {
+ for (File file : files) {
+ if (!file.isDirectory()) {
+ Slog.i(TAG, "Pruning dalvik file: " + file.getAbsolutePath());
+ file.delete();
+ } else {
+ File[] subDirList = file.listFiles();
+ if (subDirList != null) {
+ for (File subDirFile : subDirList) {
+ final String fn = subDirFile.getName();
+ if (fn.startsWith("data@app@") || fn.startsWith("data@app-private@")) {
+ Slog.i(TAG, "Pruning dalvik file: " + fn);
+ subDirFile.delete();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
public boolean isFirstBoot() {
return !mRestoredSettings;
}
@@ -1766,7 +1839,6 @@ public class PackageManagerService extends IPackageManager.Stub {
PackageInfo generatePackageInfo(PackageParser.Package p, int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
- PackageInfo pi;
final PackageSetting ps = (PackageSetting) p.mExtras;
if (ps == null) {
return null;
@@ -1979,6 +2051,7 @@ public class PackageManagerService extends IPackageManager.Stub {
pkg.applicationInfo.dataDir =
getDataPathForPackage(packageName, 0).getPath();
pkg.applicationInfo.nativeLibraryDir = ps.nativeLibraryPathString;
+ pkg.applicationInfo.requiredCpuAbi = ps.requiredCpuAbiString;
}
return generatePackageInfo(pkg, flags, userId);
}
@@ -3502,6 +3575,56 @@ public class PackageManagerService extends IPackageManager.Stub {
return finalList;
}
+ private void createIdmapsForPackageLI(PackageParser.Package pkg) {
+ HashMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName);
+ if (overlays == null) {
+ Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages");
+ return;
+ }
+ for (PackageParser.Package opkg : overlays.values()) {
+ // Not much to do if idmap fails: we already logged the error
+ // and we certainly don't want to abort installation of pkg simply
+ // because an overlay didn't fit properly. For these reasons,
+ // ignore the return value of createIdmapForPackagePairLI.
+ createIdmapForPackagePairLI(pkg, opkg);
+ }
+ }
+
+ private boolean createIdmapForPackagePairLI(PackageParser.Package pkg,
+ PackageParser.Package opkg) {
+ if (!opkg.mTrustedOverlay) {
+ Slog.w(TAG, "Skipping target and overlay pair " + pkg.mScanPath + " and " +
+ opkg.mScanPath + ": overlay not trusted");
+ return false;
+ }
+ HashMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName);
+ if (overlaySet == null) {
+ Slog.e(TAG, "was about to create idmap for " + pkg.mScanPath + " and " +
+ opkg.mScanPath + " but target package has no known overlays");
+ return false;
+ }
+ final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
+ if (mInstaller.idmap(pkg.mScanPath, opkg.mScanPath, sharedGid) != 0) {
+ Slog.e(TAG, "Failed to generate idmap for " + pkg.mScanPath + " and " + opkg.mScanPath);
+ return false;
+ }
+ PackageParser.Package[] overlayArray =
+ overlaySet.values().toArray(new PackageParser.Package[0]);
+ Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
+ public int compare(PackageParser.Package p1, PackageParser.Package p2) {
+ return p1.mOverlayPriority - p2.mOverlayPriority;
+ }
+ };
+ Arrays.sort(overlayArray, cmp);
+
+ pkg.applicationInfo.resourceDirs = new String[overlayArray.length];
+ int i = 0;
+ for (PackageParser.Package p : overlayArray) {
+ pkg.applicationInfo.resourceDirs[i++] = p.applicationInfo.sourceDir;
+ }
+ return true;
+ }
+
private void scanDirLI(File dir, int flags, int scanMode, long currentTime) {
String[] files = dir.list();
if (files == null) {
@@ -3599,7 +3722,7 @@ public class PackageManagerService extends IPackageManager.Stub {
pp.setSeparateProcesses(mSeparateProcesses);
pp.setOnlyCoreApps(mOnlyCore);
final PackageParser.Package pkg = pp.parsePackage(scanFile,
- scanPath, mMetrics, parseFlags);
+ scanPath, mMetrics, parseFlags, (scanMode & SCAN_TRUSTED_OVERLAY) != 0);
if (pkg == null) {
mLastScanError = pp.getParseError();
@@ -3627,6 +3750,7 @@ public class PackageManagerService extends IPackageManager.Stub {
updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
}
+ boolean updatedPkgBetter = false;
// First check if this is a system package that may involve an update
if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
if (ps != null && !ps.codePath.equals(scanFile)) {
@@ -3674,13 +3798,15 @@ public class PackageManagerService extends IPackageManager.Stub {
+ " better than installed " + ps.versionCode);
InstallArgs args = createInstallArgs(packageFlagsToInstallFlags(ps),
- ps.codePathString, ps.resourcePathString, ps.nativeLibraryPathString);
+ ps.codePathString, ps.resourcePathString, ps.nativeLibraryPathString,
+ getAppInstructionSetFromSettings(ps));
synchronized (mInstallLock) {
args.cleanUpResourcesLI();
}
synchronized (mPackages) {
mSettings.enableSystemPackageLPw(ps.name);
}
+ updatedPkgBetter = true;
}
}
}
@@ -3737,7 +3863,8 @@ public class PackageManagerService extends IPackageManager.Stub {
+ ps.codePathString + ": new version " + pkg.mVersionCode
+ " better than installed " + ps.versionCode);
InstallArgs args = createInstallArgs(packageFlagsToInstallFlags(ps),
- ps.codePathString, ps.resourcePathString, ps.nativeLibraryPathString);
+ ps.codePathString, ps.resourcePathString, ps.nativeLibraryPathString,
+ getAppInstructionSetFromSettings(ps));
synchronized (mInstallLock) {
args.cleanUpResourcesLI();
}
@@ -3757,7 +3884,7 @@ public class PackageManagerService extends IPackageManager.Stub {
String codePath = null;
String resPath = null;
- if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0) {
+ if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) {
if (ps != null && ps.resourcePathString != null) {
resPath = ps.resourcePathString;
} else {
@@ -3850,12 +3977,16 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
+ @Override
public void performBootDexOpt() {
- HashSet<PackageParser.Package> pkgs = null;
+ enforceSystemOrRoot("Only the system can request dexopt be performed");
+
+ final HashSet<PackageParser.Package> pkgs;
synchronized (mPackages) {
pkgs = mDeferredDexOpt;
mDeferredDexOpt = null;
}
+
if (pkgs != null) {
int i = 0;
for (PackageParser.Package pkg : pkgs) {
@@ -3872,16 +4003,17 @@ public class PackageManagerService extends IPackageManager.Stub {
PackageParser.Package p = pkg;
synchronized (mInstallLock) {
if (!p.mDidDexOpt) {
- performDexOptLI(p, false, false, true);
+ performDexOptLI(p, false /* force dex */, false /* defer */,
+ true /* include dependencies */);
}
}
}
}
}
+ @Override
public boolean performDexOpt(String packageName) {
enforceSystemOrRoot("Only the system can request dexopt be performed");
-
if (!mNoDexOpt) {
return false;
}
@@ -3894,12 +4026,13 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
synchronized (mInstallLock) {
- return performDexOptLI(p, false, false, true) == DEX_OPT_PERFORMED;
+ return performDexOptLI(p, false /* force dex */, false /* defer */,
+ true /* include dependencies */) == DEX_OPT_PERFORMED;
}
}
- private void performDexOptLibsLI(ArrayList<String> libs, boolean forceDex, boolean defer,
- HashSet<String> done) {
+ private void performDexOptLibsLI(ArrayList<String> libs, String instructionSet, boolean forceDex,
+ boolean defer, HashSet<String> done) {
for (int i=0; i<libs.size(); i++) {
PackageParser.Package libPkg;
String libName;
@@ -3913,7 +4046,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
if (libPkg != null && !done.contains(libName)) {
- performDexOptLI(libPkg, forceDex, defer, done);
+ performDexOptLI(libPkg, instructionSet, forceDex, defer, done);
}
}
}
@@ -3923,23 +4056,29 @@ public class PackageManagerService extends IPackageManager.Stub {
static final int DEX_OPT_DEFERRED = 2;
static final int DEX_OPT_FAILED = -1;
- private int performDexOptLI(PackageParser.Package pkg, boolean forceDex, boolean defer,
- HashSet<String> done) {
- boolean performed = false;
+ private int performDexOptLI(PackageParser.Package pkg, String instructionSetOverride,
+ boolean forceDex,
+ boolean defer, HashSet<String> done) {
+ final String instructionSet = instructionSetOverride != null ?
+ instructionSetOverride : getAppInstructionSet(pkg.applicationInfo);
+
if (done != null) {
done.add(pkg.packageName);
if (pkg.usesLibraries != null) {
- performDexOptLibsLI(pkg.usesLibraries, forceDex, defer, done);
+ performDexOptLibsLI(pkg.usesLibraries, instructionSet, forceDex, defer, done);
}
if (pkg.usesOptionalLibraries != null) {
- performDexOptLibsLI(pkg.usesOptionalLibraries, forceDex, defer, done);
+ performDexOptLibsLI(pkg.usesOptionalLibraries, instructionSet, forceDex, defer, done);
}
}
+
+ boolean performed = false;
if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) {
String path = pkg.mScanPath;
int ret = 0;
try {
- if (forceDex || dalvik.system.DexFile.isDexOptNeeded(path)) {
+ if (forceDex || dalvik.system.DexFile.isDexOptNeededInternal(path,
+ pkg.packageName, instructionSet, defer)) {
if (!forceDex && defer) {
if (mDeferredDexOpt == null) {
mDeferredDexOpt = new HashSet<PackageParser.Package>();
@@ -3947,9 +4086,12 @@ public class PackageManagerService extends IPackageManager.Stub {
mDeferredDexOpt.add(pkg);
return DEX_OPT_DEFERRED;
} else {
- Log.i(TAG, "Running dexopt on: " + pkg.applicationInfo.packageName);
+ Log.i(TAG, "Running dexopt on: " + pkg.applicationInfo.packageName +
+ " (instructionSet=" + instructionSet + ")");
+
final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
- ret = mInstaller.dexopt(path, sharedGid, !isForwardLocked(pkg));
+ ret = mInstaller.dexopt(path, sharedGid, !isForwardLocked(pkg),
+ pkg.packageName, instructionSet);
pkg.mDidDexOpt = true;
performed = true;
}
@@ -3976,17 +4118,58 @@ public class PackageManagerService extends IPackageManager.Stub {
return performed ? DEX_OPT_PERFORMED : DEX_OPT_SKIPPED;
}
+ private String getAppInstructionSet(ApplicationInfo info) {
+ String instructionSet = getPreferredInstructionSet();
+
+ if (info.requiredCpuAbi != null) {
+ instructionSet = VMRuntime.getInstructionSet(info.requiredCpuAbi);
+ }
+
+ return instructionSet;
+ }
+
+ private String getAppInstructionSetFromSettings(PackageSetting ps) {
+ String instructionSet = getPreferredInstructionSet();
+
+ if (ps.requiredCpuAbiString != null) {
+ instructionSet = VMRuntime.getInstructionSet(ps.requiredCpuAbiString);
+ }
+
+ return instructionSet;
+ }
+
+ private static String getPreferredInstructionSet() {
+ if (sPreferredInstructionSet == null) {
+ sPreferredInstructionSet = VMRuntime.getInstructionSet(Build.SUPPORTED_ABIS[0]);
+ }
+
+ return sPreferredInstructionSet;
+ }
+
+ private static List<String> getAllInstructionSets() {
+ final String[] allAbis = Build.SUPPORTED_ABIS;
+ final List<String> allInstructionSets = new ArrayList<String>(allAbis.length);
+
+ for (String abi : allAbis) {
+ final String instructionSet = VMRuntime.getInstructionSet(abi);
+ if (!allInstructionSets.contains(instructionSet)) {
+ allInstructionSets.add(instructionSet);
+ }
+ }
+
+ return allInstructionSets;
+ }
+
private int performDexOptLI(PackageParser.Package pkg, boolean forceDex, boolean defer,
boolean inclDependencies) {
HashSet<String> done;
- boolean performed = false;
if (inclDependencies && (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null)) {
done = new HashSet<String>();
done.add(pkg.packageName);
} else {
done = null;
}
- return performDexOptLI(pkg, forceDex, defer, done);
+ return performDexOptLI(pkg, null /* instruction set override */, forceDex, defer, done);
}
private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
@@ -4090,6 +4273,14 @@ public class PackageManagerService extends IPackageManager.Stub {
private boolean updateSharedLibrariesLPw(PackageParser.Package pkg,
PackageParser.Package changingLib) {
+ // We might be upgrading from a version of the platform that did not
+ // provide per-package native library directories for system apps.
+ // Fix that up here.
+ if (isSystemApp(pkg)) {
+ PackageSetting ps = mSettings.mPackages.get(pkg.applicationInfo.packageName);
+ setInternalAppNativeLibraryPath(pkg, ps);
+ }
+
if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) {
if (mTmpSharedLibraries == null ||
mTmpSharedLibraries.length < mSharedLibraries.size()) {
@@ -4255,17 +4446,6 @@ public class PackageManagerService extends IPackageManager.Stub {
// writer
synchronized (mPackages) {
- if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
- // Check all shared libraries and map to their actual file path.
- // We only do this here for apps not on a system dir, because those
- // are the only ones that can fail an install due to this. We
- // will take care of the system apps by updating all of their
- // library paths after the scan is done.
- if (!updateSharedLibrariesLPw(pkg, null)) {
- return null;
- }
- }
-
if (pkg.mSharedUserId != null) {
suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, true);
if (suid == null) {
@@ -4340,6 +4520,7 @@ public class PackageManagerService extends IPackageManager.Stub {
// the PkgSetting exists already and doesn't have to be created.
pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile,
destResourceFile, pkg.applicationInfo.nativeLibraryDir,
+ pkg.applicationInfo.requiredCpuAbi,
pkg.applicationInfo.flags, user, false);
if (pkgSetting == null) {
Slog.w(TAG, "Creating application package " + pkg.packageName + " failed");
@@ -4375,6 +4556,17 @@ public class PackageManagerService extends IPackageManager.Stub {
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
}
+ if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
+ // Check all shared libraries and map to their actual file path.
+ // We only do this here for apps not on a system dir, because those
+ // are the only ones that can fail an install due to this. We
+ // will take care of the system apps by updating all of their
+ // library paths after the scan is done.
+ if (!updateSharedLibrariesLPw(pkg, null)) {
+ return null;
+ }
+ }
+
if (mFoundPolicyFile) {
SELinuxMMAC.assignSeinfoValue(pkg);
}
@@ -4475,7 +4667,7 @@ public class PackageManagerService extends IPackageManager.Stub {
if (dataPath.exists()) {
int currentUid = 0;
try {
- StructStat stat = Libcore.os.stat(dataPath.getPath());
+ StructStat stat = Os.stat(dataPath.getPath());
currentUid = stat.st_uid;
} catch (ErrnoException e) {
Slog.e(TAG, "Couldn't stat path " + dataPath.getPath(), e);
@@ -4558,6 +4750,11 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
pkg.applicationInfo.dataDir = dataPath.getPath();
+ if (mShouldRestoreconData) {
+ Slog.i(TAG, "SELinux relabeling of " + pkg.packageName + " issued.");
+ mInstaller.restoreconData(pkg.packageName, pkg.applicationInfo.seinfo,
+ pkg.applicationInfo.uid);
+ }
} else {
if (DEBUG_PACKAGE_SCANNING) {
if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
@@ -4596,7 +4793,6 @@ public class PackageManagerService extends IPackageManager.Stub {
pkg.applicationInfo.nativeLibraryDir = pkgSetting.nativeLibraryPathString;
}
}
-
pkgSetting.uidError = uidError;
}
@@ -4628,6 +4824,8 @@ public class PackageManagerService extends IPackageManager.Stub {
Log.i(TAG, "removed obsolete native libraries for system package "
+ path);
}
+
+ setInternalAppAbi(pkg, pkgSetting);
} else {
if (!isForwardLocked(pkg) && !isExternal(pkg)) {
/*
@@ -4640,16 +4838,47 @@ public class PackageManagerService extends IPackageManager.Stub {
}
try {
- if (copyNativeLibrariesForInternalApp(scanFile, nativeLibraryDir) != PackageManager.INSTALL_SUCCEEDED) {
+ int copyRet = copyNativeLibrariesForInternalApp(scanFile, nativeLibraryDir);
+ if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
Slog.e(TAG, "Unable to copy native libraries");
mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
return null;
}
+
+ // We've successfully copied native libraries across, so we make a
+ // note of what ABI we're using
+ if (copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
+ pkg.applicationInfo.requiredCpuAbi = Build.SUPPORTED_ABIS[copyRet];
+ } else {
+ pkg.applicationInfo.requiredCpuAbi = null;
+ }
} catch (IOException e) {
Slog.e(TAG, "Unable to copy native libraries", e);
mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
return null;
}
+ } else {
+ // We don't have to copy the shared libraries if we're in the ASEC container
+ // but we still need to scan the file to figure out what ABI the app needs.
+ //
+ // TODO: This duplicates work done in the default container service. It's possible
+ // to clean this up but we'll need to change the interface between this service
+ // and IMediaContainerService (but doing so will spread this logic out, rather
+ // than centralizing it).
+ final NativeLibraryHelper.ApkHandle handle = new NativeLibraryHelper.ApkHandle(scanFile);
+ final int abi = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_ABIS);
+ if (abi >= 0) {
+ pkg.applicationInfo.requiredCpuAbi = Build.SUPPORTED_ABIS[abi];
+ } else if (abi == PackageManager.NO_NATIVE_LIBRARIES) {
+ // Note that (non upgraded) system apps will not have any native
+ // libraries bundled in their APK, but we're guaranteed not to be
+ // such an app at this point.
+ pkg.applicationInfo.requiredCpuAbi = null;
+ } else {
+ mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
+ return null;
+ }
+ handle.close();
}
if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path);
@@ -4726,8 +4955,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
if (allowed) {
if (!mSharedLibraries.containsKey(name)) {
- mSharedLibraries.put(name, new SharedLibraryEntry(null,
- pkg.packageName));
+ mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName));
} else if (!name.equals(pkg.packageName)) {
Slog.w(TAG, "Package " + pkg.packageName + " library "
+ name + " already exists; skipping");
@@ -4800,6 +5028,12 @@ public class PackageManagerService extends IPackageManager.Stub {
// writer
synchronized (mPackages) {
+ if ((scanMode&SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
+ // We don't do this here during boot because we can do it all
+ // at once after scanning all existing packages.
+ adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages,
+ true, forceDex, (scanMode & SCAN_DEFER_DEX) != 0);
+ }
// We don't expect installation to fail beyond this point,
if ((scanMode&SCAN_MONITOR) != 0) {
mAppDirs.put(pkg.mPath, pkg);
@@ -5115,11 +5349,83 @@ public class PackageManagerService extends IPackageManager.Stub {
}
pkgSetting.setTimeStamp(scanFileTime);
+
+ // Create idmap files for pairs of (packages, overlay packages).
+ // Note: "android", ie framework-res.apk, is handled by native layers.
+ if (pkg.mOverlayTarget != null) {
+ // This is an overlay package.
+ if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) {
+ if (!mOverlays.containsKey(pkg.mOverlayTarget)) {
+ mOverlays.put(pkg.mOverlayTarget,
+ new HashMap<String, PackageParser.Package>());
+ }
+ HashMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget);
+ map.put(pkg.packageName, pkg);
+ PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget);
+ if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) {
+ mLastScanError = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
+ return null;
+ }
+ }
+ } else if (mOverlays.containsKey(pkg.packageName) &&
+ !pkg.packageName.equals("android")) {
+ // This is a regular package, with one or more known overlay packages.
+ createIdmapsForPackageLI(pkg);
+ }
}
return pkg;
}
+ public void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
+ boolean doDexOpt, boolean forceDexOpt, boolean deferDexOpt) {
+ String requiredInstructionSet = null;
+ PackageSetting requirer = null;
+ for (PackageSetting ps : packagesForUser) {
+ if (ps.requiredCpuAbiString != null) {
+ final String instructionSet = VMRuntime.getInstructionSet(ps.requiredCpuAbiString);
+ if (requiredInstructionSet != null) {
+ if (!instructionSet.equals(requiredInstructionSet)) {
+ // We have a mismatch between instruction sets (say arm vs arm64).
+ //
+ // TODO: We should rescan all the packages in a shared UID to check if
+ // they do contain shared libs for other ABIs in addition to the ones we've
+ // already extracted. For example, the package might contain both arm64-v8a
+ // and armeabi-v7a shared libs, and we'd have chosen arm64-v8a on 64 bit
+ // devices.
+ String errorMessage = "Instruction set mismatch, " + requirer.pkg.packageName
+ + " requires " + requiredInstructionSet + " whereas " + ps.pkg.packageName
+ + " requires " + instructionSet;
+ Slog.e(TAG, errorMessage);
+
+ reportSettingsProblem(Log.WARN, errorMessage);
+ // Give up, don't bother making any other changes to the package settings.
+ return;
+ }
+ } else {
+ requiredInstructionSet = instructionSet;
+ requirer = ps;
+ }
+ }
+ }
+
+ if (requiredInstructionSet != null) {
+ for (PackageSetting ps : packagesForUser) {
+ if (ps.requiredCpuAbiString == null) {
+ ps.requiredCpuAbiString = requirer.requiredCpuAbiString;
+ if (ps.pkg != null) {
+ ps.pkg.applicationInfo.requiredCpuAbi = requirer.requiredCpuAbiString;
+ Slog.i(TAG, "Adjusting ABI for : " + ps.name + " to " + ps.requiredCpuAbiString);
+ if (doDexOpt) {
+ performDexOptLI(ps.pkg, forceDexOpt, deferDexOpt, true);
+ mInstaller.rmdex(ps.codePathString, getPreferredInstructionSet());
+ }
+ }
+ }
+ }
+ }
+ }
+
private void setUpCustomResolverActivity(PackageParser.Package pkg) {
synchronized (mPackages) {
mResolverReplaced = true;
@@ -5144,14 +5450,86 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
+ private String calculateApkRoot(final String codePathString) {
+ final File codePath = new File(codePathString);
+ final File codeRoot;
+ if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
+ codeRoot = Environment.getRootDirectory();
+ } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
+ codeRoot = Environment.getOemDirectory();
+ } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
+ codeRoot = Environment.getVendorDirectory();
+ } else {
+ // Unrecognized code path; take its top real segment as the apk root:
+ // e.g. /something/app/blah.apk => /something
+ try {
+ File f = codePath.getCanonicalFile();
+ File parent = f.getParentFile(); // non-null because codePath is a file
+ File tmp;
+ while ((tmp = parent.getParentFile()) != null) {
+ f = parent;
+ parent = tmp;
+ }
+ codeRoot = f;
+ Slog.w(TAG, "Unrecognized code path "
+ + codePath + " - using " + codeRoot);
+ } catch (IOException e) {
+ // Can't canonicalize the lib path -- shenanigans?
+ Slog.w(TAG, "Can't canonicalize code path " + codePath);
+ return Environment.getRootDirectory().getPath();
+ }
+ }
+ return codeRoot.getPath();
+ }
+
+ // This is the initial scan-time determination of how to handle a given
+ // package for purposes of native library location.
private void setInternalAppNativeLibraryPath(PackageParser.Package pkg,
PackageSetting pkgSetting) {
- final String apkLibPath = getApkName(pkgSetting.codePathString);
- final String nativeLibraryPath = new File(mAppLibInstallDir, apkLibPath).getPath();
+ // "bundled" here means system-installed with no overriding update
+ final boolean bundledApk = isSystemApp(pkg) && !isUpdatedSystemApp(pkg);
+ final String apkName = getApkName(pkg.applicationInfo.sourceDir);
+ final File libDir;
+ if (bundledApk) {
+ // If "/system/lib64/apkname" exists, assume that is the per-package
+ // native library directory to use; otherwise use "/system/lib/apkname".
+ String apkRoot = calculateApkRoot(pkg.applicationInfo.sourceDir);
+ File lib64 = new File(apkRoot, LIB64_DIR_NAME);
+ File packLib64 = new File(lib64, apkName);
+ libDir = (packLib64.exists()) ? lib64 : new File(apkRoot, LIB_DIR_NAME);
+ } else {
+ libDir = mAppLibInstallDir;
+ }
+ final String nativeLibraryPath = (new File(libDir, apkName)).getPath();
pkg.applicationInfo.nativeLibraryDir = nativeLibraryPath;
pkgSetting.nativeLibraryPathString = nativeLibraryPath;
}
+ // Deduces the required ABI of an upgraded system app.
+ private void setInternalAppAbi(PackageParser.Package pkg, PackageSetting pkgSetting) {
+ final String apkRoot = calculateApkRoot(pkg.applicationInfo.sourceDir);
+ final String apkName = getApkName(pkg.applicationInfo.sourceDir);
+
+ // This is of the form "/system/lib64/<packagename>", "/vendor/lib64/<packagename>"
+ // or similar.
+ final File lib64 = new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath());
+ final File lib = new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath());
+
+ // Assume that the bundled native libraries always correspond to the
+ // most preferred 32 or 64 bit ABI.
+ if (lib64.exists()) {
+ pkg.applicationInfo.requiredCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
+ pkgSetting.requiredCpuAbiString = Build.SUPPORTED_64_BIT_ABIS[0];
+ } else if (lib.exists()) {
+ pkg.applicationInfo.requiredCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
+ pkgSetting.requiredCpuAbiString = Build.SUPPORTED_32_BIT_ABIS[0];
+ } else {
+ // This is the case where the app has no native code.
+ pkg.applicationInfo.requiredCpuAbi = null;
+ pkgSetting.requiredCpuAbiString = null;
+ }
+ }
+
private static int copyNativeLibrariesForInternalApp(File scanFile, final File nativeLibraryDir)
throws IOException {
if (!nativeLibraryDir.isDirectory()) {
@@ -5162,8 +5540,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
try {
- Libcore.os.chmod(nativeLibraryDir.getPath(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH
- | S_IXOTH);
+ Os.chmod(nativeLibraryDir.getPath(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
} catch (ErrnoException e) {
throw new IOException("Cannot chmod native library directory "
+ nativeLibraryDir.getPath(), e);
@@ -5176,7 +5553,21 @@ public class PackageManagerService extends IPackageManager.Stub {
* If this is an internal application or our nativeLibraryPath points to
* the app-lib directory, unpack the libraries if necessary.
*/
- return NativeLibraryHelper.copyNativeBinariesIfNeededLI(scanFile, nativeLibraryDir);
+ final NativeLibraryHelper.ApkHandle handle = new NativeLibraryHelper.ApkHandle(scanFile);
+ try {
+ int abi = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_ABIS);
+ if (abi >= 0) {
+ int copyRet = NativeLibraryHelper.copyNativeBinariesIfNeededLI(handle,
+ nativeLibraryDir, Build.SUPPORTED_ABIS[abi]);
+ if (copyRet != PackageManager.INSTALL_SUCCEEDED) {
+ return copyRet;
+ }
+ }
+
+ return abi;
+ } finally {
+ handle.close();
+ }
}
private void killApplication(String pkgName, int appId, String reason) {
@@ -7719,7 +8110,8 @@ public class PackageManagerService extends IPackageManager.Stub {
int mRet;
MoveParams(InstallArgs srcArgs, IPackageMoveObserver observer, int flags,
- String packageName, String dataDir, int uid, UserHandle user) {
+ String packageName, String dataDir, String instructionSet,
+ int uid, UserHandle user) {
super(user);
this.srcArgs = srcArgs;
this.observer = observer;
@@ -7728,7 +8120,7 @@ public class PackageManagerService extends IPackageManager.Stub {
this.uid = uid;
if (srcArgs != null) {
Uri packageUri = Uri.fromFile(new File(srcArgs.getCodePath()));
- targetArgs = createInstallArgs(packageUri, flags, packageName, dataDir);
+ targetArgs = createInstallArgs(packageUri, flags, packageName, dataDir, instructionSet);
} else {
targetArgs = null;
}
@@ -7837,7 +8229,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
private InstallArgs createInstallArgs(int flags, String fullCodePath, String fullResourcePath,
- String nativeLibraryPath) {
+ String nativeLibraryPath, String instructionSet) {
final boolean isInAsec;
if (installOnSd(flags)) {
/* Apps on SD card are always in ASEC containers. */
@@ -7855,21 +8247,23 @@ public class PackageManagerService extends IPackageManager.Stub {
if (isInAsec) {
return new AsecInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath,
- installOnSd(flags), installForwardLocked(flags));
+ instructionSet, installOnSd(flags), installForwardLocked(flags));
} else {
- return new FileInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath);
+ return new FileInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath,
+ instructionSet);
}
}
// Used by package mover
- private InstallArgs createInstallArgs(Uri packageURI, int flags, String pkgName, String dataDir) {
+ private InstallArgs createInstallArgs(Uri packageURI, int flags, String pkgName, String dataDir,
+ String instructionSet) {
if (installOnSd(flags) || installForwardLocked(flags)) {
String cid = getNextCodePath(packageURI.getPath(), pkgName, "/"
+ AsecInstallArgs.RES_FILE_NAME);
- return new AsecInstallArgs(packageURI, cid, installOnSd(flags),
+ return new AsecInstallArgs(packageURI, cid, instructionSet, installOnSd(flags),
installForwardLocked(flags));
} else {
- return new FileInstallArgs(packageURI, pkgName, dataDir);
+ return new FileInstallArgs(packageURI, pkgName, dataDir, instructionSet);
}
}
@@ -7881,16 +8275,18 @@ public class PackageManagerService extends IPackageManager.Stub {
final String installerPackageName;
final ManifestDigest manifestDigest;
final UserHandle user;
+ final String instructionSet;
InstallArgs(Uri packageURI, IPackageInstallObserver observer, int flags,
String installerPackageName, ManifestDigest manifestDigest,
- UserHandle user) {
+ UserHandle user, String instructionSet) {
this.packageURI = packageURI;
this.flags = flags;
this.observer = observer;
this.installerPackageName = installerPackageName;
this.manifestDigest = manifestDigest;
this.user = user;
+ this.instructionSet = instructionSet;
}
abstract void createCopyFile();
@@ -7946,11 +8342,12 @@ public class PackageManagerService extends IPackageManager.Stub {
FileInstallArgs(InstallParams params) {
super(params.getPackageUri(), params.observer, params.flags,
params.installerPackageName, params.getManifestDigest(),
- params.getUser());
+ params.getUser(), null /* instruction set */);
}
- FileInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath) {
- super(null, null, 0, null, null, null);
+ FileInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath,
+ String instructionSet) {
+ super(null, null, 0, null, null, null, instructionSet);
File codeFile = new File(fullCodePath);
installDir = codeFile.getParentFile();
codeFileName = fullCodePath;
@@ -7958,8 +8355,8 @@ public class PackageManagerService extends IPackageManager.Stub {
libraryPath = nativeLibraryPath;
}
- FileInstallArgs(Uri packageURI, String pkgName, String dataDir) {
- super(packageURI, null, 0, null, null, null);
+ FileInstallArgs(Uri packageURI, String pkgName, String dataDir, String instructionSet) {
+ super(packageURI, null, 0, null, null, null, instructionSet);
installDir = isFwdLocked() ? mDrmAppPrivateInstallDir : mAppInstallDir;
String apkName = getNextCodePath(null, pkgName, ".apk");
codeFileName = new File(installDir, apkName + ".apk").getPath();
@@ -8065,7 +8462,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
try {
int copyRet = copyNativeLibrariesForInternalApp(codeFile, nativeLibraryFile);
- if (copyRet != PackageManager.INSTALL_SUCCEEDED) {
+ if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
return copyRet;
}
} catch (IOException e) {
@@ -8218,7 +8615,10 @@ public class PackageManagerService extends IPackageManager.Stub {
void cleanUpResourcesLI() {
String sourceDir = getCodePath();
if (cleanUp()) {
- int retCode = mInstaller.rmdex(sourceDir);
+ if (instructionSet == null) {
+ throw new IllegalStateException("instructionSet == null");
+ }
+ int retCode = mInstaller.rmdex(sourceDir, instructionSet);
if (retCode < 0) {
Slog.w(TAG, "Couldn't remove dex file for package: "
+ " at location "
@@ -8282,14 +8682,14 @@ public class PackageManagerService extends IPackageManager.Stub {
AsecInstallArgs(InstallParams params) {
super(params.getPackageUri(), params.observer, params.flags,
params.installerPackageName, params.getManifestDigest(),
- params.getUser());
+ params.getUser(), null /* instruction set */);
}
AsecInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath,
- boolean isExternal, boolean isForwardLocked) {
+ String instructionSet, boolean isExternal, boolean isForwardLocked) {
super(null, null, (isExternal ? PackageManager.INSTALL_EXTERNAL : 0)
| (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0),
- null, null, null);
+ null, null, null, instructionSet);
// Extract cid from fullCodePath
int eidx = fullCodePath.lastIndexOf("/");
String subStr1 = fullCodePath.substring(0, eidx);
@@ -8298,18 +8698,19 @@ public class PackageManagerService extends IPackageManager.Stub {
setCachePath(subStr1);
}
- AsecInstallArgs(String cid, boolean isForwardLocked) {
+ AsecInstallArgs(String cid, String instructionSet, boolean isForwardLocked) {
super(null, null, (isAsecExternal(cid) ? PackageManager.INSTALL_EXTERNAL : 0)
| (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0),
- null, null, null);
+ null, null, null, instructionSet);
this.cid = cid;
setCachePath(PackageHelper.getSdDir(cid));
}
- AsecInstallArgs(Uri packageURI, String cid, boolean isExternal, boolean isForwardLocked) {
+ AsecInstallArgs(Uri packageURI, String cid, String instructionSet,
+ boolean isExternal, boolean isForwardLocked) {
super(packageURI, null, (isExternal ? PackageManager.INSTALL_EXTERNAL : 0)
| (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0),
- null, null, null);
+ null, null, null, instructionSet);
this.cid = cid;
}
@@ -8490,7 +8891,10 @@ public class PackageManagerService extends IPackageManager.Stub {
void cleanUpResourcesLI() {
String sourceFile = getCodePath();
// Remove dex file
- int retCode = mInstaller.rmdex(sourceFile);
+ if (instructionSet == null) {
+ throw new IllegalStateException("instructionSet == null");
+ }
+ int retCode = mInstaller.rmdex(sourceFile, instructionSet);
if (retCode < 0) {
Slog.w(TAG, "Couldn't remove dex file for package: "
+ " at location "
@@ -8871,7 +9275,8 @@ public class PackageManagerService extends IPackageManager.Stub {
res.removedInfo.args = createInstallArgs(0,
deletedPackage.applicationInfo.sourceDir,
deletedPackage.applicationInfo.publicSourceDir,
- deletedPackage.applicationInfo.nativeLibraryDir);
+ deletedPackage.applicationInfo.nativeLibraryDir,
+ getAppInstructionSet(deletedPackage.applicationInfo));
} else {
res.removedInfo.args = null;
}
@@ -8920,7 +9325,8 @@ public class PackageManagerService extends IPackageManager.Stub {
private int moveDexFilesLI(PackageParser.Package newPackage) {
int retCode;
if ((newPackage.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) {
- retCode = mInstaller.movedex(newPackage.mScanPath, newPackage.mPath);
+ retCode = mInstaller.movedex(newPackage.mScanPath, newPackage.mPath,
+ getAppInstructionSet(newPackage.applicationInfo));
if (retCode != 0) {
if (mNoDexOpt) {
/*
@@ -9544,13 +9950,14 @@ public class PackageManagerService extends IPackageManager.Stub {
}
// writer
synchronized (mPackages) {
+ PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
+ setInternalAppNativeLibraryPath(newPkg, ps);
updatePermissionsLPw(newPkg.packageName, newPkg,
UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
if (applyUserRestrictions) {
if (DEBUG_REMOVE) {
Slog.d(TAG, "Propagating install state across reinstall");
}
- PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
for (int i = 0; i < allUserHandles.length; i++) {
if (DEBUG_REMOVE) {
Slog.d(TAG, " user " + allUserHandles[i]
@@ -9584,7 +9991,8 @@ public class PackageManagerService extends IPackageManager.Stub {
// Delete application code and resources
if (deleteCodeAndResources && (outInfo != null)) {
outInfo.args = createInstallArgs(packageFlagsToInstallFlags(ps), ps.codePathString,
- ps.resourcePathString, ps.nativeLibraryPathString);
+ ps.resourcePathString, ps.nativeLibraryPathString,
+ getAppInstructionSetFromSettings(ps));
}
return true;
}
@@ -9951,9 +10359,10 @@ public class PackageManagerService extends IPackageManager.Stub {
boolean dataOnly = false;
String libDirPath = null;
String asecPath = null;
+ PackageSetting ps = null;
synchronized (mPackages) {
p = mPackages.get(packageName);
- PackageSetting ps = mSettings.mPackages.get(packageName);
+ ps = mSettings.mPackages.get(packageName);
if(p == null) {
dataOnly = true;
if((ps == null) || (ps.pkg == null)) {
@@ -9984,7 +10393,8 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
int res = mInstaller.getSizeInfo(packageName, userHandle, p.mPath, libDirPath,
- publicSrcDir, asecPath, pStats);
+ publicSrcDir, asecPath, getAppInstructionSetFromSettings(ps),
+ pStats);
if (res < 0) {
return false;
}
@@ -11026,6 +11436,10 @@ public class PackageManagerService extends IPackageManager.Stub {
*/
public void scanAvailableAsecs() {
updateExternalMediaStatusInner(true, false, false);
+ if (mShouldRestoreconData) {
+ SELinuxMMAC.setRestoreconDone();
+ mShouldRestoreconData = false;
+ }
}
/*
@@ -11081,7 +11495,9 @@ public class PackageManagerService extends IPackageManager.Stub {
continue;
}
- final AsecInstallArgs args = new AsecInstallArgs(cid, isForwardLocked(ps));
+ final AsecInstallArgs args = new AsecInstallArgs(cid,
+ getAppInstructionSetFromSettings(ps),
+ isForwardLocked(ps));
// The package status is changed only if the code path
// matches between settings and the container id.
if (ps.codePathString != null && ps.codePathString.equals(args.getCodePath())) {
@@ -11396,15 +11812,17 @@ public class PackageManagerService extends IPackageManager.Stub {
* anyway.
*/
if (returnCode != PackageManager.MOVE_SUCCEEDED) {
- processPendingMove(new MoveParams(null, observer, 0, packageName,
+ processPendingMove(new MoveParams(null, observer, 0, packageName, null,
null, -1, user),
returnCode);
} else {
Message msg = mHandler.obtainMessage(INIT_COPY);
+ final String instructionSet = getAppInstructionSet(pkg.applicationInfo);
InstallArgs srcArgs = createInstallArgs(currFlags, pkg.applicationInfo.sourceDir,
- pkg.applicationInfo.publicSourceDir, pkg.applicationInfo.nativeLibraryDir);
+ pkg.applicationInfo.publicSourceDir, pkg.applicationInfo.nativeLibraryDir,
+ instructionSet);
MoveParams mp = new MoveParams(srcArgs, observer, newFlags, packageName,
- pkg.applicationInfo.dataDir, pkg.applicationInfo.uid, user);
+ pkg.applicationInfo.dataDir, instructionSet, pkg.applicationInfo.uid, user);
msg.obj = mp;
mHandler.sendMessage(msg);
}
@@ -11471,8 +11889,17 @@ public class PackageManagerService extends IPackageManager.Stub {
final File newNativeDir = new File(newNativePath);
if (!isForwardLocked(pkg) && !isExternal(pkg)) {
- NativeLibraryHelper.copyNativeBinariesIfNeededLI(
- new File(newCodePath), newNativeDir);
+ // NOTE: We do not report any errors from the APK scan and library
+ // copy at this point.
+ NativeLibraryHelper.ApkHandle handle =
+ new NativeLibraryHelper.ApkHandle(newCodePath);
+ final int abi = NativeLibraryHelper.findSupportedAbi(
+ handle, Build.SUPPORTED_ABIS);
+ if (abi >= 0) {
+ NativeLibraryHelper.copyNativeBinariesIfNeededLI(
+ handle, newNativeDir, Build.SUPPORTED_ABIS[abi]);
+ }
+ handle.close();
}
final int[] users = sUserManager.getUserIds();
for (int user : users) {
diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java
index b447861..15df3d2 100644
--- a/services/core/java/com/android/server/pm/PackageSetting.java
+++ b/services/core/java/com/android/server/pm/PackageSetting.java
@@ -30,8 +30,8 @@ final class PackageSetting extends PackageSettingBase {
SharedUserSetting sharedUser;
PackageSetting(String name, String realName, File codePath, File resourcePath,
- String nativeLibraryPathString, int pVersionCode, int pkgFlags) {
- super(name, realName, codePath, resourcePath, nativeLibraryPathString, pVersionCode,
+ String nativeLibraryPathString, String requiredCpuAbiString, int pVersionCode, int pkgFlags) {
+ super(name, realName, codePath, resourcePath, nativeLibraryPathString, requiredCpuAbiString, pVersionCode,
pkgFlags);
}
diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java
index 7747c8f..ba95b9a 100644
--- a/services/core/java/com/android/server/pm/PackageSettingBase.java
+++ b/services/core/java/com/android/server/pm/PackageSettingBase.java
@@ -53,6 +53,7 @@ class PackageSettingBase extends GrantedPermissions {
File resourcePath;
String resourcePathString;
String nativeLibraryPathString;
+ String requiredCpuAbiString;
long timeStamp;
long firstInstallTime;
long lastUpdateTime;
@@ -80,11 +81,11 @@ class PackageSettingBase extends GrantedPermissions {
/* 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) {
+ String nativeLibraryPathString, String requiredCpuAbiString, int pVersionCode, int pkgFlags) {
super(pkgFlags);
this.name = name;
this.realName = realName;
- init(codePath, resourcePath, nativeLibraryPathString, pVersionCode);
+ init(codePath, resourcePath, nativeLibraryPathString, requiredCpuAbiString, pVersionCode);
}
/**
@@ -101,6 +102,7 @@ class PackageSettingBase extends GrantedPermissions {
resourcePath = base.resourcePath;
resourcePathString = base.resourcePathString;
nativeLibraryPathString = base.nativeLibraryPathString;
+ requiredCpuAbiString = base.requiredCpuAbiString;
timeStamp = base.timeStamp;
firstInstallTime = base.firstInstallTime;
lastUpdateTime = base.lastUpdateTime;
@@ -128,12 +130,13 @@ class PackageSettingBase extends GrantedPermissions {
}
void init(File codePath, File resourcePath, String nativeLibraryPathString,
- int pVersionCode) {
+ String requiredCpuAbiString, int pVersionCode) {
this.codePath = codePath;
this.codePathString = codePath.toString();
this.resourcePath = resourcePath;
this.resourcePathString = resourcePath.toString();
this.nativeLibraryPathString = nativeLibraryPathString;
+ this.requiredCpuAbiString = requiredCpuAbiString;
this.versionCode = pVersionCode;
}
@@ -164,6 +167,7 @@ class PackageSettingBase extends GrantedPermissions {
grantedPermissions = base.grantedPermissions;
gids = base.gids;
+ requiredCpuAbiString = base.requiredCpuAbiString;
timeStamp = base.timeStamp;
firstInstallTime = base.firstInstallTime;
lastUpdateTime = base.lastUpdateTime;
diff --git a/services/core/java/com/android/server/pm/PendingPackage.java b/services/core/java/com/android/server/pm/PendingPackage.java
index c17cc46..36c3a34 100644
--- a/services/core/java/com/android/server/pm/PendingPackage.java
+++ b/services/core/java/com/android/server/pm/PendingPackage.java
@@ -22,8 +22,8 @@ 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,
+ String nativeLibraryPathString, String requiredCpuAbiString, int sharedId, int pVersionCode, int pkgFlags) {
+ super(name, realName, codePath, resourcePath, nativeLibraryPathString, requiredCpuAbiString, pVersionCode,
pkgFlags);
this.sharedId = sharedId;
}
diff --git a/services/core/java/com/android/server/pm/SELinuxMMAC.java b/services/core/java/com/android/server/pm/SELinuxMMAC.java
index 1d68afa..d70c725 100644
--- a/services/core/java/com/android/server/pm/SELinuxMMAC.java
+++ b/services/core/java/com/android/server/pm/SELinuxMMAC.java
@@ -25,11 +25,15 @@ import android.util.Xml;
import com.android.internal.util.XmlUtils;
+import libcore.io.IoUtils;
+
import java.io.File;
-import java.io.FileInputStream;
import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
@@ -60,6 +64,13 @@ public final class SELinuxMMAC {
new File(Environment.getRootDirectory(), "etc/security/mac_permissions.xml"),
null};
+ // Location of seapp_contexts policy file.
+ private static final String SEAPP_CONTEXTS_FILE = "/seapp_contexts";
+
+ // Stores the hash of the last used seapp_contexts file.
+ private static final String SEAPP_HASH_FILE =
+ Environment.getDataDirectory().toString() + "/system/seapp_hash";
+
// Signature policy stanzas
static class Policy {
private String seinfo;
@@ -103,7 +114,6 @@ public final class SELinuxMMAC {
/**
* Parses an MMAC install policy from a predefined list of locations.
- * @param none
* @return boolean indicating whether an install policy was correctly parsed.
*/
public static boolean readInstallPolicy() {
@@ -113,7 +123,7 @@ public final class SELinuxMMAC {
/**
* Parses an MMAC install policy given as an argument.
- * @param File object representing the path of the policy.
+ * @param policyFile object representing the path of the policy.
* @return boolean indicating whether the install policy was correctly parsed.
*/
public static boolean readInstallPolicy(File policyFile) {
@@ -345,8 +355,7 @@ public final class SELinuxMMAC {
/**
* Labels a package based on an seinfo tag from install policy.
* The label is attached to the ApplicationInfo instance of the package.
- * @param PackageParser.Package object representing the package
- * to labeled.
+ * @param pkg object representing the package to be labeled.
* @return boolean which determines whether a non null seinfo label
* was assigned to the package. A null value simply meaning that
* no policy matched.
@@ -391,4 +400,89 @@ public final class SELinuxMMAC {
return (sDefaultSeinfo != null);
}
+
+ /**
+ * Determines if a recursive restorecon on /data/data and /data/user is needed.
+ * It does this by comparing the SHA-1 of the seapp_contexts file against the
+ * stored hash at /data/system/seapp_hash.
+ *
+ * @return Returns true if the restorecon should occur or false otherwise.
+ */
+ public static boolean shouldRestorecon() {
+ // Any error with the seapp_contexts file should be fatal
+ byte[] currentHash = null;
+ try {
+ currentHash = returnHash(SEAPP_CONTEXTS_FILE);
+ } catch (IOException ioe) {
+ Slog.e(TAG, "Error with hashing seapp_contexts.", ioe);
+ return false;
+ }
+
+ // Push past any error with the stored hash file
+ byte[] storedHash = null;
+ try {
+ storedHash = IoUtils.readFileAsByteArray(SEAPP_HASH_FILE);
+ } catch (IOException ioe) {
+ Slog.w(TAG, "Error opening " + SEAPP_HASH_FILE + ". Assuming first boot.");
+ }
+
+ return (storedHash == null || !MessageDigest.isEqual(storedHash, currentHash));
+ }
+
+ /**
+ * Stores the SHA-1 of the seapp_contexts to /data/system/seapp_hash.
+ */
+ public static void setRestoreconDone() {
+ try {
+ final byte[] currentHash = returnHash(SEAPP_CONTEXTS_FILE);
+ dumpHash(new File(SEAPP_HASH_FILE), currentHash);
+ } catch (IOException ioe) {
+ Slog.e(TAG, "Error with saving hash to " + SEAPP_HASH_FILE, ioe);
+ }
+ }
+
+ /**
+ * Dump the contents of a byte array to a specified file.
+ *
+ * @param file The file that receives the byte array content.
+ * @param content A byte array that will be written to the specified file.
+ * @throws IOException if any failed I/O operation occured.
+ * Included is the failure to atomically rename the tmp
+ * file used in the process.
+ */
+ private static void dumpHash(File file, byte[] content) throws IOException {
+ FileOutputStream fos = null;
+ File tmp = null;
+ try {
+ tmp = File.createTempFile("seapp_hash", ".journal", file.getParentFile());
+ tmp.setReadable(true);
+ fos = new FileOutputStream(tmp);
+ fos.write(content);
+ fos.getFD().sync();
+ if (!tmp.renameTo(file)) {
+ throw new IOException("Failure renaming " + file.getCanonicalPath());
+ }
+ } finally {
+ if (tmp != null) {
+ tmp.delete();
+ }
+ IoUtils.closeQuietly(fos);
+ }
+ }
+
+ /**
+ * Return the SHA-1 of a file.
+ *
+ * @param file The path to the file given as a string.
+ * @return Returns the SHA-1 of the file as a byte array.
+ * @throws IOException if any failed I/O operations occured.
+ */
+ private static byte[] returnHash(String file) throws IOException {
+ try {
+ final byte[] contents = IoUtils.readFileAsByteArray(file);
+ return MessageDigest.getInstance("SHA-1").digest(contents);
+ } catch (NoSuchAlgorithmException nsae) {
+ throw new RuntimeException(nsae); // impossible
+ }
+ }
}
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 8f18b23..27ec1bf 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -36,6 +36,7 @@ import com.android.internal.util.JournaledFile;
import com.android.internal.util.XmlUtils;
import com.android.server.pm.PackageManagerService.DumpState;
+import java.util.Collection;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
@@ -213,10 +214,10 @@ final class Settings {
PackageSetting getPackageLPw(PackageParser.Package pkg, PackageSetting origPackage,
String realName, SharedUserSetting sharedUser, File codePath, File resourcePath,
- String nativeLibraryPathString, int pkgFlags, UserHandle user, boolean add) {
+ String nativeLibraryPathString, String requiredCpuAbiString, int pkgFlags, UserHandle user, boolean add) {
final String name = pkg.packageName;
PackageSetting p = getPackageLPw(name, origPackage, realName, sharedUser, codePath,
- resourcePath, nativeLibraryPathString, pkg.mVersionCode, pkgFlags,
+ resourcePath, nativeLibraryPathString, requiredCpuAbiString, pkg.mVersionCode, pkgFlags,
user, add, true /* allowInstall */);
return p;
}
@@ -262,6 +263,11 @@ final class Settings {
return s;
}
+ Collection<SharedUserSetting> getAllSharedUsersLPw() {
+ return mSharedUsers.values();
+ }
+
+
boolean disableSystemPackageLPw(String name) {
final PackageSetting p = mPackages.get(name);
if(p == null) {
@@ -298,7 +304,7 @@ final class Settings {
p.pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
}
PackageSetting ret = addPackageLPw(name, p.realName, p.codePath, p.resourcePath,
- p.nativeLibraryPathString, p.appId, p.versionCode, p.pkgFlags);
+ p.nativeLibraryPathString, p.requiredCpuAbiString, p.appId, p.versionCode, p.pkgFlags);
mDisabledSysPackages.remove(name);
return ret;
}
@@ -312,7 +318,7 @@ final class Settings {
}
PackageSetting addPackageLPw(String name, String realName, File codePath, File resourcePath,
- String nativeLibraryPathString, int uid, int vc, int pkgFlags) {
+ String nativeLibraryPathString, String requiredCpuAbiString, int uid, int vc, int pkgFlags) {
PackageSetting p = mPackages.get(name);
if (p != null) {
if (p.appId == uid) {
@@ -322,7 +328,7 @@ final class Settings {
"Adding duplicate package, keeping first: " + name);
return null;
}
- p = new PackageSetting(name, realName, codePath, resourcePath, nativeLibraryPathString,
+ p = new PackageSetting(name, realName, codePath, resourcePath, nativeLibraryPathString, requiredCpuAbiString,
vc, pkgFlags);
p.appId = uid;
if (addUserIdLPw(uid, p, name)) {
@@ -391,10 +397,11 @@ final class Settings {
private PackageSetting getPackageLPw(String name, PackageSetting origPackage,
String realName, SharedUserSetting sharedUser, File codePath, File resourcePath,
- String nativeLibraryPathString, int vc, int pkgFlags,
+ String nativeLibraryPathString, String requiredCpuAbiString, int vc, int pkgFlags,
UserHandle installUser, boolean add, boolean allowInstall) {
PackageSetting p = mPackages.get(name);
if (p != null) {
+ p.requiredCpuAbiString = requiredCpuAbiString;
if (!p.codePath.equals(codePath)) {
// Check to see if its a disabled system app
if ((p.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
@@ -438,7 +445,7 @@ final class Settings {
if (origPackage != null) {
// We are consuming the data from an existing package.
p = new PackageSetting(origPackage.name, name, codePath, resourcePath,
- nativeLibraryPathString, vc, pkgFlags);
+ nativeLibraryPathString, requiredCpuAbiString, vc, pkgFlags);
if (PackageManagerService.DEBUG_UPGRADE) Log.v(PackageManagerService.TAG, "Package "
+ name + " is adopting original package " + origPackage.name);
// Note that we will retain the new package's signature so
@@ -455,7 +462,7 @@ final class Settings {
p.setTimeStamp(codePath.lastModified());
} else {
p = new PackageSetting(name, realName, codePath, resourcePath,
- nativeLibraryPathString, vc, pkgFlags);
+ nativeLibraryPathString, requiredCpuAbiString, vc, pkgFlags);
p.setTimeStamp(codePath.lastModified());
p.sharedUser = sharedUser;
// If this is not a system app, it starts out stopped.
@@ -581,6 +588,8 @@ final class Settings {
&& !nativeLibraryPath.equalsIgnoreCase(p.nativeLibraryPathString)) {
p.nativeLibraryPathString = nativeLibraryPath;
}
+ // Update the required Cpu Abi
+ p.requiredCpuAbiString = pkg.applicationInfo.requiredCpuAbi;
// Update version code if needed
if (pkg.mVersionCode != p.versionCode) {
p.versionCode = pkg.mVersionCode;
@@ -1427,6 +1436,7 @@ final class Settings {
// FROM NATIVE CODE. AT THE MOMENT, LOOK AT THE FOLLOWING SOURCES:
// system/core/run-as/run-as.c
// system/core/sdcard/sdcard.c
+ // external/libselinux/src/android.c:package_info_init()
//
sb.setLength(0);
sb.append(ai.packageName);
@@ -1497,6 +1507,9 @@ final class Settings {
if (pkg.nativeLibraryPathString != null) {
serializer.attribute(null, "nativeLibraryPath", pkg.nativeLibraryPathString);
}
+ if (pkg.requiredCpuAbiString != null) {
+ serializer.attribute(null, "requiredCpuAbi", pkg.requiredCpuAbiString);
+ }
if (pkg.sharedUser == null) {
serializer.attribute(null, "userId", Integer.toString(pkg.appId));
} else {
@@ -1539,6 +1552,9 @@ final class Settings {
if (pkg.nativeLibraryPathString != null) {
serializer.attribute(null, "nativeLibraryPath", pkg.nativeLibraryPathString);
}
+ if (pkg.requiredCpuAbiString != null) {
+ serializer.attribute(null, "requiredCpuAbi", pkg.requiredCpuAbiString);
+ }
serializer.attribute(null, "flags", Integer.toString(pkg.pkgFlags));
serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp));
serializer.attribute(null, "it", Long.toHexString(pkg.firstInstallTime));
@@ -1803,7 +1819,7 @@ final class Settings {
if (idObj != null && idObj instanceof SharedUserSetting) {
PackageSetting p = getPackageLPw(pp.name, null, pp.realName,
(SharedUserSetting) idObj, pp.codePath, pp.resourcePath,
- pp.nativeLibraryPathString, pp.versionCode, pp.pkgFlags,
+ pp.nativeLibraryPathString, pp.requiredCpuAbiString, pp.versionCode, pp.pkgFlags,
null, true /* add */, false /* allowInstall */);
if (p == null) {
PackageManagerService.reportSettingsProblem(Log.WARN,
@@ -2223,6 +2239,8 @@ final class Settings {
String codePathStr = parser.getAttributeValue(null, "codePath");
String resourcePathStr = parser.getAttributeValue(null, "resourcePath");
String nativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
+ String requiredCpuAbiString = parser.getAttributeValue(null, "requiredCpuAbi");
+
if (resourcePathStr == null) {
resourcePathStr = codePathStr;
}
@@ -2242,7 +2260,7 @@ final class Settings {
pkgFlags |= ApplicationInfo.FLAG_PRIVILEGED;
}
PackageSetting ps = new PackageSetting(name, realName, codePathFile,
- new File(resourcePathStr), nativeLibraryPathStr, versionCode, pkgFlags);
+ new File(resourcePathStr), nativeLibraryPathStr, requiredCpuAbiString, versionCode, pkgFlags);
String timeStampStr = parser.getAttributeValue(null, "ft");
if (timeStampStr != null) {
try {
@@ -2309,6 +2327,7 @@ final class Settings {
String codePathStr = null;
String resourcePathStr = null;
String nativeLibraryPathStr = null;
+ String requiredCpuAbiString = null;
String systemStr = null;
String installerPackageName = null;
String uidError = null;
@@ -2328,6 +2347,8 @@ final class Settings {
codePathStr = parser.getAttributeValue(null, "codePath");
resourcePathStr = parser.getAttributeValue(null, "resourcePath");
nativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
+ requiredCpuAbiString = parser.getAttributeValue(null, "requiredCpuAbi");
+
version = parser.getAttributeValue(null, "version");
if (version != null) {
try {
@@ -2404,7 +2425,7 @@ final class Settings {
+ parser.getPositionDescription());
} else if (userId > 0) {
packageSetting = addPackageLPw(name.intern(), realName, new File(codePathStr),
- new File(resourcePathStr), nativeLibraryPathStr, userId, versionCode,
+ new File(resourcePathStr), nativeLibraryPathStr, requiredCpuAbiString, userId, versionCode,
pkgFlags);
if (PackageManagerService.DEBUG_SETTINGS)
Log.i(PackageManagerService.TAG, "Reading package " + name + ": userId="
@@ -2422,7 +2443,7 @@ final class Settings {
userId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
if (userId > 0) {
packageSetting = new PendingPackage(name.intern(), realName, new File(
- codePathStr), new File(resourcePathStr), nativeLibraryPathStr, userId,
+ codePathStr), new File(resourcePathStr), nativeLibraryPathStr, requiredCpuAbiString, userId,
versionCode, pkgFlags);
packageSetting.setTimeStamp(timeStamp);
packageSetting.firstInstallTime = firstInstallTime;
@@ -2451,6 +2472,7 @@ final class Settings {
packageSetting.uidError = "true".equals(uidError);
packageSetting.installerPackageName = installerPackageName;
packageSetting.nativeLibraryPathString = nativeLibraryPathStr;
+ packageSetting.requiredCpuAbiString = requiredCpuAbiString;
// Handle legacy string here for single-user mode
final String enabledStr = parser.getAttributeValue(null, ATTR_ENABLED);
if (enabledStr != null) {
@@ -2950,6 +2972,7 @@ final class Settings {
pw.print(prefix); pw.print(" codePath="); pw.println(ps.codePathString);
pw.print(prefix); pw.print(" resourcePath="); pw.println(ps.resourcePathString);
pw.print(prefix); pw.print(" nativeLibraryPath="); pw.println(ps.nativeLibraryPathString);
+ pw.print(prefix); pw.print(" requiredCpuAbi="); pw.println(ps.requiredCpuAbiString);
pw.print(prefix); pw.print(" versionCode="); pw.print(ps.versionCode);
if (ps.pkg != null) {
pw.print(" targetSdk="); pw.print(ps.pkg.applicationInfo.targetSdkVersion);
diff --git a/services/core/java/com/android/server/updates/SELinuxPolicyInstallReceiver.java b/services/core/java/com/android/server/updates/SELinuxPolicyInstallReceiver.java
index e430814..3c960c7 100644
--- a/services/core/java/com/android/server/updates/SELinuxPolicyInstallReceiver.java
+++ b/services/core/java/com/android/server/updates/SELinuxPolicyInstallReceiver.java
@@ -18,10 +18,10 @@ package com.android.server.updates;
import android.content.Context;
import android.content.Intent;
-import android.os.FileUtils;
-import android.os.SELinux;
import android.os.SystemProperties;
import android.provider.Settings;
+import android.system.ErrnoException;
+import android.system.Os;
import android.util.Base64;
import android.util.Slog;
@@ -30,9 +30,7 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
-import libcore.io.ErrnoException;
import libcore.io.IoUtils;
-import libcore.io.Libcore;
public class SELinuxPolicyInstallReceiver extends ConfigUpdateInstallReceiver {
@@ -112,16 +110,16 @@ public class SELinuxPolicyInstallReceiver extends ConfigUpdateInstallReceiver {
File update = new File(updateDir.getParentFile(), "update");
File tmp = new File(updateDir.getParentFile(), "tmp");
if (current.exists()) {
- Libcore.os.symlink(updateDir.getPath(), update.getPath());
- Libcore.os.rename(update.getPath(), current.getPath());
+ Os.symlink(updateDir.getPath(), update.getPath());
+ Os.rename(update.getPath(), current.getPath());
} else {
- Libcore.os.symlink(updateDir.getPath(), current.getPath());
+ Os.symlink(updateDir.getPath(), current.getPath());
}
contexts.mkdirs();
backupContexts(contexts);
copyUpdate(contexts);
- Libcore.os.symlink(contexts.getPath(), tmp.getPath());
- Libcore.os.rename(tmp.getPath(), current.getPath());
+ Os.symlink(contexts.getPath(), tmp.getPath());
+ Os.rename(tmp.getPath(), current.getPath());
SystemProperties.set("selinux.reload_policy", "1");
}
diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
index e630737..f79896b 100644
--- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -199,7 +199,8 @@ class ScreenRotationAnimation {
}
public ScreenRotationAnimation(Context context, DisplayContent displayContent,
- SurfaceSession session, boolean inTransaction, boolean forceDefaultOrientation) {
+ SurfaceSession session, boolean inTransaction, boolean forceDefaultOrientation,
+ boolean isSecure) {
mContext = context;
mDisplayContent = displayContent;
displayContent.getLogicalDisplayRect(mOriginalDisplayRect);
@@ -241,16 +242,21 @@ class ScreenRotationAnimation {
try {
try {
+ int flags = SurfaceControl.HIDDEN;
+ if (isSecure) {
+ flags |= SurfaceControl.SECURE;
+ }
+
if (WindowManagerService.DEBUG_SURFACE_TRACE) {
mSurfaceControl = new SurfaceTrace(session, "ScreenshotSurface",
mWidth, mHeight,
- PixelFormat.OPAQUE, SurfaceControl.HIDDEN);
+ PixelFormat.OPAQUE, flags);
Slog.w(TAG, "ScreenRotationAnimation ctor: displayOffset="
+ mOriginalDisplayRect.toShortString());
} else {
mSurfaceControl = new SurfaceControl(session, "ScreenshotSurface",
mWidth, mHeight,
- PixelFormat.OPAQUE, SurfaceControl.HIDDEN);
+ PixelFormat.OPAQUE, flags);
}
// capture a screenshot into the surface we just created
Surface sur = new Surface();
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 081cffd..6cdbdeb 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -3543,8 +3543,9 @@ public class WindowManagerService extends IWindowManager.Stub
Task newTask = mTaskIdToTask.get(groupId);
if (newTask == null) {
newTask = createTask(groupId, oldTask.mStack.mStackId, oldTask.mUserId, atoken);
+ } else {
+ newTask.mAppTokens.add(atoken);
}
- newTask.mAppTokens.add(atoken);
}
}
@@ -10028,10 +10029,22 @@ public class WindowManagerService extends IWindowManager.Stub
screenRotationAnimation.kill();
}
+ // Check whether the current screen contains any secure content.
+ boolean isSecure = false;
+ final WindowList windows = getDefaultWindowListLocked();
+ final int N = windows.size();
+ for (int i = 0; i < N; i++) {
+ WindowState ws = windows.get(i);
+ if (ws.isOnScreen() && (ws.mAttrs.flags & FLAG_SECURE) != 0) {
+ isSecure = true;
+ break;
+ }
+ }
+
// TODO(multidisplay): rotation on main screen only.
displayContent.updateDisplayInfo();
screenRotationAnimation = new ScreenRotationAnimation(mContext, displayContent,
- mFxSession, inTransaction, mPolicy.isDefaultOrientationForced());
+ mFxSession, inTransaction, mPolicy.isDefaultOrientationForced(), isSecure);
mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation);
}
}
diff --git a/services/core/jni/com_android_server_AlarmManagerService.cpp b/services/core/jni/com_android_server_AlarmManagerService.cpp
index 342515b..a58b00bce 100644
--- a/services/core/jni/com_android_server_AlarmManagerService.cpp
+++ b/services/core/jni/com_android_server_AlarmManagerService.cpp
@@ -36,6 +36,7 @@
#include <unistd.h>
#include <linux/ioctl.h>
#include <linux/android_alarm.h>
+#include <linux/rtc.h>
namespace android {
@@ -58,6 +59,7 @@ public:
virtual ~AlarmImpl();
virtual int set(int type, struct timespec *ts) = 0;
+ virtual int setTime(struct timeval *tv) = 0;
virtual int waitForAlarm() = 0;
protected:
@@ -71,6 +73,7 @@ public:
AlarmImplAlarmDriver(int fd) : AlarmImpl(&fd, 1) { }
int set(int type, struct timespec *ts);
+ int setTime(struct timeval *tv);
int waitForAlarm();
};
@@ -82,6 +85,7 @@ public:
~AlarmImplTimerFd();
int set(int type, struct timespec *ts);
+ int setTime(struct timeval *tv);
int waitForAlarm();
private:
@@ -107,6 +111,19 @@ int AlarmImplAlarmDriver::set(int type, struct timespec *ts)
return ioctl(fds[0], ANDROID_ALARM_SET(type), ts);
}
+int AlarmImplAlarmDriver::setTime(struct timeval *tv)
+{
+ struct timespec ts;
+ int res;
+
+ ts.tv_sec = tv->tv_sec;
+ ts.tv_nsec = tv->tv_usec * 1000;
+ res = ioctl(fds[0], ANDROID_ALARM_SET_RTC, &ts);
+ if (res < 0)
+ ALOGV("ANDROID_ALARM_SET_RTC ioctl failed: %s\n", strerror(errno));
+ return res;
+}
+
int AlarmImplAlarmDriver::waitForAlarm()
{
return ioctl(fds[0], ANDROID_ALARM_WAIT);
@@ -140,6 +157,50 @@ int AlarmImplTimerFd::set(int type, struct timespec *ts)
return timerfd_settime(fds[type], TFD_TIMER_ABSTIME, &spec, NULL);
}
+int AlarmImplTimerFd::setTime(struct timeval *tv)
+{
+ struct rtc_time rtc;
+ struct tm tm, *gmtime_res;
+ int fd;
+ int res;
+
+ res = settimeofday(tv, NULL);
+ if (res < 0) {
+ ALOGV("settimeofday() failed: %s\n", strerror(errno));
+ return -1;
+ }
+
+ fd = open("/dev/rtc0", O_RDWR);
+ if (fd < 0) {
+ ALOGV("Unable to open RTC driver: %s\n", strerror(errno));
+ return res;
+ }
+
+ gmtime_res = gmtime_r(&tv->tv_sec, &tm);
+ if (!gmtime_res) {
+ ALOGV("gmtime_r() failed: %s\n", strerror(errno));
+ res = -1;
+ goto done;
+ }
+
+ memset(&rtc, 0, sizeof(rtc));
+ rtc.tm_sec = tm.tm_sec;
+ rtc.tm_min = tm.tm_min;
+ rtc.tm_hour = tm.tm_hour;
+ rtc.tm_mday = tm.tm_mday;
+ rtc.tm_mon = tm.tm_mon;
+ rtc.tm_year = tm.tm_year;
+ rtc.tm_wday = tm.tm_wday;
+ rtc.tm_yday = tm.tm_yday;
+ rtc.tm_isdst = tm.tm_isdst;
+ res = ioctl(fd, RTC_SET_TIME, &rtc);
+ if (res < 0)
+ ALOGV("RTC_SET_TIME ioctl failed: %s\n", strerror(errno));
+done:
+ close(fd);
+ return res;
+}
+
int AlarmImplTimerFd::waitForAlarm()
{
epoll_event events[N_ANDROID_TIMERFDS];
@@ -168,6 +229,30 @@ int AlarmImplTimerFd::waitForAlarm()
return result;
}
+static jint android_server_AlarmManagerService_setKernelTime(JNIEnv*, jobject, jlong nativeData, jlong millis)
+{
+ AlarmImpl *impl = reinterpret_cast<AlarmImpl *>(nativeData);
+ struct timeval tv;
+ int ret;
+
+ if (millis <= 0 || millis / 1000LL >= INT_MAX) {
+ return -1;
+ }
+
+ tv.tv_sec = (time_t) (millis / 1000LL);
+ tv.tv_usec = (suseconds_t) ((millis % 1000LL) * 1000LL);
+
+ ALOGD("Setting time of day to sec=%d\n", (int) tv.tv_sec);
+
+ ret = impl->setTime(&tv);
+
+ if(ret < 0) {
+ ALOGW("Unable to set rtc to %ld: %s\n", tv.tv_sec, strerror(errno));
+ ret = -1;
+ }
+ return ret;
+}
+
static jint android_server_AlarmManagerService_setKernelTimezone(JNIEnv*, jobject, jlong, jint minswest)
{
struct timezone tz;
@@ -280,7 +365,9 @@ static void android_server_AlarmManagerService_set(JNIEnv*, jobject, jlong nativ
int result = impl->set(type, &ts);
if (result < 0)
{
- ALOGE("Unable to set alarm to %lld.%09lld: %s\n", seconds, nanoseconds, strerror(errno));
+ ALOGE("Unable to set alarm to %lld.%09lld: %s\n",
+ static_cast<long long>(seconds),
+ static_cast<long long>(nanoseconds), strerror(errno));
}
}
@@ -309,6 +396,7 @@ static JNINativeMethod sMethods[] = {
{"close", "(J)V", (void*)android_server_AlarmManagerService_close},
{"set", "(JIJJ)V", (void*)android_server_AlarmManagerService_set},
{"waitForAlarm", "(J)I", (void*)android_server_AlarmManagerService_waitForAlarm},
+ {"setKernelTime", "(JJ)I", (void*)android_server_AlarmManagerService_setKernelTime},
{"setKernelTimezone", "(JI)I", (void*)android_server_AlarmManagerService_setKernelTimezone},
};
diff --git a/services/core/jni/com_android_server_AssetAtlasService.cpp b/services/core/jni/com_android_server_AssetAtlasService.cpp
index 4a1b55d..163692b 100644
--- a/services/core/jni/com_android_server_AssetAtlasService.cpp
+++ b/services/core/jni/com_android_server_AssetAtlasService.cpp
@@ -73,7 +73,7 @@ static inline void swapCanvasPtr(JNIEnv* env, jobject canvasObj, SkCanvas* newCa
SkSafeUnref(previousCanvas);
}
-static SkBitmap* com_android_server_AssetAtlasService_acquireCanvas(JNIEnv* env, jobject,
+static jlong com_android_server_AssetAtlasService_acquireCanvas(JNIEnv* env, jobject,
jobject canvas, jint width, jint height) {
SkBitmap* bitmap = new SkBitmap;
@@ -84,12 +84,13 @@ static SkBitmap* com_android_server_AssetAtlasService_acquireCanvas(JNIEnv* env,
SkCanvas* nativeCanvas = SkNEW_ARGS(SkCanvas, (*bitmap));
swapCanvasPtr(env, canvas, nativeCanvas);
- return bitmap;
+ return reinterpret_cast<jlong>(bitmap);
}
static void com_android_server_AssetAtlasService_releaseCanvas(JNIEnv* env, jobject,
- jobject canvas, SkBitmap* bitmap) {
+ jobject canvas, jlong bitmapHandle) {
+ SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
SkCanvas* nativeCanvas = SkNEW(SkCanvas);
swapCanvasPtr(env, canvas, nativeCanvas);
@@ -108,21 +109,22 @@ static void com_android_server_AssetAtlasService_releaseCanvas(JNIEnv* env, jobj
return result;
static jboolean com_android_server_AssetAtlasService_upload(JNIEnv* env, jobject,
- jobject graphicBuffer, SkBitmap* bitmap) {
+ jobject graphicBuffer, jlong bitmapHandle) {
+ SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
// The goal of this method is to copy the bitmap into the GraphicBuffer
// using the GPU to swizzle the texture content
sp<GraphicBuffer> buffer(graphicBufferForJavaObject(env, graphicBuffer));
if (buffer != NULL) {
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- if (display == EGL_NO_DISPLAY) return false;
+ if (display == EGL_NO_DISPLAY) return JNI_FALSE;
EGLint major;
EGLint minor;
if (!eglInitialize(display, &major, &minor)) {
ALOGW("Could not initialize EGL");
- return false;
+ return JNI_FALSE;
}
// We're going to use a 1x1 pbuffer surface later on
@@ -143,13 +145,13 @@ static jboolean com_android_server_AssetAtlasService_upload(JNIEnv* env, jobject
ALOGW("Could not select EGL configuration");
eglReleaseThread();
eglTerminate(display);
- return false;
+ return JNI_FALSE;
}
if (configCount <= 0) {
ALOGW("Could not find EGL configuration");
eglReleaseThread();
eglTerminate(display);
- return false;
+ return JNI_FALSE;
}
// These objects are initialized below but the default "null"
@@ -164,7 +166,7 @@ static jboolean com_android_server_AssetAtlasService_upload(JNIEnv* env, jobject
EGLContext context = eglCreateContext(display, configs[0], EGL_NO_CONTEXT, attrs);
if (context == EGL_NO_CONTEXT) {
ALOGW("Could not create EGL context");
- CLEANUP_GL_AND_RETURN(false);
+ CLEANUP_GL_AND_RETURN(JNI_FALSE);
}
// Create the 1x1 pbuffer
@@ -172,12 +174,12 @@ static jboolean com_android_server_AssetAtlasService_upload(JNIEnv* env, jobject
surface = eglCreatePbufferSurface(display, configs[0], surfaceAttrs);
if (surface == EGL_NO_SURFACE) {
ALOGW("Could not create EGL surface");
- CLEANUP_GL_AND_RETURN(false);
+ CLEANUP_GL_AND_RETURN(JNI_FALSE);
}
if (!eglMakeCurrent(display, surface, surface, context)) {
ALOGW("Could not change current EGL context");
- CLEANUP_GL_AND_RETURN(false);
+ CLEANUP_GL_AND_RETURN(JNI_FALSE);
}
// We use an EGLImage to access the content of the GraphicBuffer
@@ -188,7 +190,7 @@ static jboolean com_android_server_AssetAtlasService_upload(JNIEnv* env, jobject
EGL_NATIVE_BUFFER_ANDROID, clientBuffer, imageAttrs);
if (image == EGL_NO_IMAGE_KHR) {
ALOGW("Could not create EGL image");
- CLEANUP_GL_AND_RETURN(false);
+ CLEANUP_GL_AND_RETURN(JNI_FALSE);
}
glGenTextures(1, &texture);
@@ -196,7 +198,7 @@ static jboolean com_android_server_AssetAtlasService_upload(JNIEnv* env, jobject
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
if (glGetError() != GL_NO_ERROR) {
ALOGW("Could not create/bind texture");
- CLEANUP_GL_AND_RETURN(false);
+ CLEANUP_GL_AND_RETURN(JNI_FALSE);
}
// Upload the content of the bitmap in the GraphicBuffer
@@ -205,7 +207,7 @@ static jboolean com_android_server_AssetAtlasService_upload(JNIEnv* env, jobject
GL_RGBA, GL_UNSIGNED_BYTE, bitmap->getPixels());
if (glGetError() != GL_NO_ERROR) {
ALOGW("Could not upload to texture");
- CLEANUP_GL_AND_RETURN(false);
+ CLEANUP_GL_AND_RETURN(JNI_FALSE);
}
// The fence is used to wait for the texture upload to finish
@@ -214,7 +216,7 @@ static jboolean com_android_server_AssetAtlasService_upload(JNIEnv* env, jobject
fence = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, NULL);
if (fence == EGL_NO_SYNC_KHR) {
ALOGW("Could not create sync fence %#x", eglGetError());
- CLEANUP_GL_AND_RETURN(false);
+ CLEANUP_GL_AND_RETURN(JNI_FALSE);
}
// The flag EGL_SYNC_FLUSH_COMMANDS_BIT_KHR will trigger a
@@ -223,13 +225,13 @@ static jboolean com_android_server_AssetAtlasService_upload(JNIEnv* env, jobject
EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, FENCE_TIMEOUT);
if (waitStatus != EGL_CONDITION_SATISFIED_KHR) {
ALOGW("Failed to wait for the fence %#x", eglGetError());
- CLEANUP_GL_AND_RETURN(false);
+ CLEANUP_GL_AND_RETURN(JNI_FALSE);
}
- CLEANUP_GL_AND_RETURN(true);
+ CLEANUP_GL_AND_RETURN(JNI_TRUE);
}
- return false;
+ return JNI_FALSE;
}
// ----------------------------------------------------------------------------
@@ -247,11 +249,11 @@ static jboolean com_android_server_AssetAtlasService_upload(JNIEnv* env, jobject
const char* const kClassPathName = "com/android/server/AssetAtlasService";
static JNINativeMethod gMethods[] = {
- { "nAcquireAtlasCanvas", "(Landroid/graphics/Canvas;II)I",
+ { "nAcquireAtlasCanvas", "(Landroid/graphics/Canvas;II)J",
(void*) com_android_server_AssetAtlasService_acquireCanvas },
- { "nReleaseAtlasCanvas", "(Landroid/graphics/Canvas;I)V",
+ { "nReleaseAtlasCanvas", "(Landroid/graphics/Canvas;J)V",
(void*) com_android_server_AssetAtlasService_releaseCanvas },
- { "nUploadAtlas", "(Landroid/view/GraphicBuffer;I)Z",
+ { "nUploadAtlas", "(Landroid/view/GraphicBuffer;J)Z",
(void*) com_android_server_AssetAtlasService_upload },
};
diff --git a/services/core/jni/com_android_server_ConsumerIrService.cpp b/services/core/jni/com_android_server_ConsumerIrService.cpp
index 004c0aa..3a50ff7 100644
--- a/services/core/jni/com_android_server_ConsumerIrService.cpp
+++ b/services/core/jni/com_android_server_ConsumerIrService.cpp
@@ -29,7 +29,7 @@
namespace android {
-static jint halOpen(JNIEnv *env, jobject obj) {
+static jlong halOpen(JNIEnv *env, jobject obj) {
hw_module_t const* module;
consumerir_device_t *dev;
int err;
@@ -47,10 +47,10 @@ static jint halOpen(JNIEnv *env, jobject obj) {
return 0;
}
- return reinterpret_cast<jint>(dev);
+ return reinterpret_cast<jlong>(dev);
}
-static jint halTransmit(JNIEnv *env, jobject obj, jint halObject,
+static jint halTransmit(JNIEnv *env, jobject obj, jlong halObject,
jint carrierFrequency, jintArray pattern) {
int ret;
@@ -67,8 +67,8 @@ static jint halTransmit(JNIEnv *env, jobject obj, jint halObject,
}
static jintArray halGetCarrierFrequencies(JNIEnv *env, jobject obj,
- jint halObject) {
- consumerir_device_t *dev = (consumerir_device_t *) halObject;
+ jlong halObject) {
+ consumerir_device_t *dev = reinterpret_cast<consumerir_device_t*>(halObject);
consumerir_freq_range_t *ranges;
int len;
@@ -101,9 +101,9 @@ static jintArray halGetCarrierFrequencies(JNIEnv *env, jobject obj,
}
static JNINativeMethod method_table[] = {
- { "halOpen", "()I", (void *)halOpen },
- { "halTransmit", "(II[I)I", (void *)halTransmit },
- { "halGetCarrierFrequencies", "(I)[I", (void *)halGetCarrierFrequencies},
+ { "halOpen", "()J", (void *)halOpen },
+ { "halTransmit", "(JI[I)I", (void *)halTransmit },
+ { "halGetCarrierFrequencies", "(J)[I", (void *)halGetCarrierFrequencies},
};
int register_android_server_ConsumerIrService(JNIEnv *env) {
diff --git a/services/core/jni/com_android_server_UsbHostManager.cpp b/services/core/jni/com_android_server_UsbHostManager.cpp
index f1fa6cf..fc6de60 100644
--- a/services/core/jni/com_android_server_UsbHostManager.cpp
+++ b/services/core/jni/com_android_server_UsbHostManager.cpp
@@ -163,8 +163,10 @@ static jobject android_server_UsbHostManager_openDevice(JNIEnv *env, jobject thi
return NULL;
int fd = usb_device_get_fd(device);
- if (fd < 0)
+ if (fd < 0) {
+ usb_device_close(device);
return NULL;
+ }
int newFD = dup(fd);
usb_device_close(device);
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 8968725..6845e8c 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -51,6 +51,7 @@ import android.view.WindowManager;
import com.android.internal.R;
import com.android.internal.os.BinderInternal;
+import com.android.internal.os.Zygote;
import com.android.internal.os.SamplingProfilerIntegration;
import com.android.server.accessibility.AccessibilityManagerService;
import com.android.server.accounts.AccountManagerService;
@@ -84,7 +85,6 @@ import com.android.server.wifi.WifiService;
import com.android.server.wm.WindowManagerService;
import dalvik.system.VMRuntime;
-import dalvik.system.Zygote;
import java.io.File;
import java.util.Timer;
@@ -167,7 +167,7 @@ public final class SystemServer {
// had to fallback to a different runtime because it is
// running as root and we need to be the system user to set
// the property. http://b/11463182
- SystemProperties.set("persist.sys.dalvik.vm.lib", VMRuntime.getRuntime().vmLibrary());
+ SystemProperties.set("persist.sys.dalvik.vm.lib.1", VMRuntime.getRuntime().vmLibrary());
// Enable the sampling profiler.
if (SamplingProfilerIntegration.isEnabled()) {
@@ -911,8 +911,6 @@ public final class SystemServer {
final boolean safeMode = wm.detectSafeMode();
if (safeMode) {
mActivityManagerService.enterSafeMode();
- // Post the safe mode state in the Zygote class
- Zygote.systemInSafeMode = true;
// Disable the JIT for the system_server process
VMRuntime.getRuntime().disableJitCompilation();
} else {
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 76a8d17..5d22ffc 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -594,14 +594,19 @@ public class UsbDeviceManager {
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
intent.putExtra("state", (enabled ? 1 : 0));
if (enabled) {
+ Scanner scanner = null;
try {
- Scanner scanner = new Scanner(new File(AUDIO_SOURCE_PCM_PATH));
+ scanner = new Scanner(new File(AUDIO_SOURCE_PCM_PATH));
int card = scanner.nextInt();
int device = scanner.nextInt();
intent.putExtra("card", card);
intent.putExtra("device", device);
} catch (FileNotFoundException e) {
Slog.e(TAG, "could not open audio source PCM file", e);
+ } finally {
+ if (scanner != null) {
+ scanner.close();
+ }
}
}
mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);