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/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.java30
-rw-r--r--services/core/java/com/android/server/am/CoreSettingsObserver.java58
-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.java24
-rwxr-xr-xservices/core/java/com/android/server/pm/PackageManagerService.java119
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java3
-rw-r--r--services/core/jni/com_android_server_AlarmManagerService.cpp86
-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.java2
19 files changed, 591 insertions, 113 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/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 ad7ec99..e6c5422 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 6c3f528..500666f 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1058,6 +1058,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 +1672,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;
+ }
}
}
};
@@ -13348,11 +13365,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/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/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..b7e367b 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -218,6 +218,30 @@ public final class Installer extends SystemService {
builder.append(' ');
builder.append(uid);
builder.append(isPublic ? " 1" : " 0");
+ builder.append(" *"); // No pkgName arg present
+ return execute(builder.toString());
+ }
+
+ public int dexopt(String apkPath, int uid, boolean isPublic, String pkgName) {
+ 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);
+ return execute(builder.toString());
+ }
+
+ 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());
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index c90978a..3f179e0 100755
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -219,6 +219,7 @@ 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_TRUSTED_OVERLAY = 1<<9;
static final int REMOVE_CHATTY = 1<<16;
@@ -259,9 +260,15 @@ public class PackageManagerService extends IPackageManager.Stub {
private static final String LIB_DIR_NAME = "lib";
+ private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
+
static final String mTempContainerPrefix = "smdl2tmp";
final ServiceThread mHandlerThread;
+
+ 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;
@@ -297,6 +304,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 +354,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;
@@ -1202,7 +1216,7 @@ public class PackageManagerService extends IPackageManager.Stub {
continue;
}
try {
- if (dalvik.system.DexFile.isDexOptNeeded(lib)) {
+ if (dalvik.system.DexFile.isDexOptNeededInternal(lib, null, false)) {
alreadyDexOpted.add(lib);
mInstaller.dexopt(lib, Process.SYSTEM_UID, true);
didDexOpt = true;
@@ -1246,7 +1260,7 @@ public class PackageManagerService extends IPackageManager.Stub {
continue;
}
try {
- if (dalvik.system.DexFile.isDexOptNeeded(path)) {
+ if (dalvik.system.DexFile.isDexOptNeededInternal(path, null, false)) {
mInstaller.dexopt(path, Process.SYSTEM_UID, true);
didDexOpt = true;
}
@@ -1279,6 +1293,17 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
+ // 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 +1332,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();
@@ -3502,6 +3532,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 +3679,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 +3707,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)) {
@@ -3681,6 +3762,7 @@ public class PackageManagerService extends IPackageManager.Stub {
synchronized (mPackages) {
mSettings.enableSystemPackageLPw(ps.name);
}
+ updatedPkgBetter = true;
}
}
}
@@ -3757,7 +3839,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 {
@@ -3939,7 +4021,8 @@ public class PackageManagerService extends IPackageManager.Stub {
String path = pkg.mScanPath;
int ret = 0;
try {
- if (forceDex || dalvik.system.DexFile.isDexOptNeeded(path)) {
+ if (forceDex || dalvik.system.DexFile.isDexOptNeededInternal(path, pkg.packageName,
+ defer)) {
if (!forceDex && defer) {
if (mDeferredDexOpt == null) {
mDeferredDexOpt = new HashSet<PackageParser.Package>();
@@ -3949,7 +4032,8 @@ public class PackageManagerService extends IPackageManager.Stub {
} else {
Log.i(TAG, "Running dexopt on: " + pkg.applicationInfo.packageName);
final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
- ret = mInstaller.dexopt(path, sharedGid, !isForwardLocked(pkg));
+ ret = mInstaller.dexopt(path, sharedGid, !isForwardLocked(pkg),
+ pkg.packageName);
pkg.mDidDexOpt = true;
performed = true;
}
@@ -5108,6 +5192,29 @@ 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;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index fb5d7a7..85036ed 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -3522,8 +3522,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);
}
}
diff --git a/services/core/jni/com_android_server_AlarmManagerService.cpp b/services/core/jni/com_android_server_AlarmManagerService.cpp
index 342515b..c26a516 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;
@@ -309,6 +394,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 db40cbe..b498c0c 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -165,7 +165,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()) {