diff options
Diffstat (limited to 'services')
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()) { |