Merge "Adding user consent extras to DevicePolicyManager."
diff --git a/Android.mk b/Android.mk
index 2f3a990..642d8b9 100644
--- a/Android.mk
+++ b/Android.mk
@@ -217,14 +217,6 @@
core/java/android/service/wallpaper/IWallpaperConnection.aidl \
core/java/android/service/wallpaper/IWallpaperEngine.aidl \
core/java/android/service/wallpaper/IWallpaperService.aidl \
- core/java/android/tv/ITvInputClient.aidl \
- core/java/android/tv/ITvInputHardware.aidl \
- core/java/android/tv/ITvInputHardwareCallback.aidl \
- core/java/android/tv/ITvInputManager.aidl \
- core/java/android/tv/ITvInputService.aidl \
- core/java/android/tv/ITvInputServiceCallback.aidl \
- core/java/android/tv/ITvInputSession.aidl \
- core/java/android/tv/ITvInputSessionCallback.aidl \
core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl\
core/java/android/view/accessibility/IAccessibilityInteractionConnectionCallback.aidl\
core/java/android/view/accessibility/IAccessibilityManager.aidl \
@@ -322,6 +314,14 @@
media/java/android/media/session/ISession.aidl \
media/java/android/media/session/ISessionCallback.aidl \
media/java/android/media/session/ISessionManager.aidl \
+ media/java/android/media/tv/ITvInputClient.aidl \
+ media/java/android/media/tv/ITvInputHardware.aidl \
+ media/java/android/media/tv/ITvInputHardwareCallback.aidl \
+ media/java/android/media/tv/ITvInputManager.aidl \
+ media/java/android/media/tv/ITvInputService.aidl \
+ media/java/android/media/tv/ITvInputServiceCallback.aidl \
+ media/java/android/media/tv/ITvInputSession.aidl \
+ media/java/android/media/tv/ITvInputSessionCallback.aidl \
telecomm/java/com/android/internal/telecomm/ICallService.aidl \
telecomm/java/com/android/internal/telecomm/ICallServiceAdapter.aidl \
telecomm/java/com/android/internal/telecomm/ICallServiceLookupResponse.aidl \
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 48a20a4..f3bb9b6 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -192,6 +192,7 @@
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/media/java/android/media/)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/app)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/src/android/app/wearable)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/tv/ITv*)
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
diff --git a/api/current.txt b/api/current.txt
index e9bae81..b5849ed 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -15979,6 +15979,160 @@
}
+package android.media.tv {
+
+ public final class TvContract {
+ method public static final android.net.Uri buildChannelUri(long);
+ method public static final android.net.Uri buildChannelsUriForInput(android.content.ComponentName);
+ method public static final android.net.Uri buildChannelsUriForInput(android.content.ComponentName, boolean);
+ method public static final android.net.Uri buildProgramUri(long);
+ method public static final android.net.Uri buildProgramsUriForChannel(android.net.Uri);
+ method public static final android.net.Uri buildProgramsUriForChannel(android.net.Uri, long, long);
+ field public static final java.lang.String AUTHORITY = "com.android.tv";
+ }
+
+ public static abstract interface TvContract.BaseTvColumns implements android.provider.BaseColumns {
+ field public static final java.lang.String COLUMN_PACKAGE_NAME = "package_name";
+ }
+
+ public static final class TvContract.Channels implements android.media.tv.TvContract.BaseTvColumns {
+ field public static final java.lang.String COLUMN_BROWSABLE = "browsable";
+ field public static final java.lang.String COLUMN_DATA = "data";
+ field public static final java.lang.String COLUMN_DESCRIPTION = "description";
+ field public static final java.lang.String COLUMN_DISPLAY_NAME = "display_name";
+ field public static final java.lang.String COLUMN_DISPLAY_NUMBER = "display_number";
+ field public static final java.lang.String COLUMN_LOCKED = "locked";
+ field public static final java.lang.String COLUMN_ORIGINAL_NETWORK_ID = "original_network_id";
+ field public static final java.lang.String COLUMN_SEARCHABLE = "searchable";
+ field public static final java.lang.String COLUMN_SERVICE_ID = "service_id";
+ field public static final java.lang.String COLUMN_SERVICE_NAME = "service_name";
+ field public static final java.lang.String COLUMN_SERVICE_TYPE = "service_type";
+ field public static final java.lang.String COLUMN_TRANSPORT_STREAM_ID = "transport_stream_id";
+ field public static final java.lang.String COLUMN_TYPE = "type";
+ field public static final java.lang.String COLUMN_VERSION_NUMBER = "version_number";
+ field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.com.android.tv.channels";
+ field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.com.android.tv.channels";
+ field public static final android.net.Uri CONTENT_URI;
+ field public static final int SERVICE_TYPE_OTHER = 0; // 0x0
+ field public static final int SERVICE_TYPE_RADIO = 2; // 0x2
+ field public static final int SERVICE_TYPE_TV = 1; // 0x1
+ field public static final int TYPE_1SEG = 263168; // 0x40400
+ field public static final int TYPE_ATSC_C = 197120; // 0x30200
+ field public static final int TYPE_ATSC_M_H = 197120; // 0x30200
+ field public static final int TYPE_ATSC_T = 196608; // 0x30000
+ field public static final int TYPE_CMMB = 327936; // 0x50100
+ field public static final int TYPE_DTMB = 327680; // 0x50000
+ field public static final int TYPE_DVB_C = 131584; // 0x20200
+ field public static final int TYPE_DVB_C2 = 131585; // 0x20201
+ field public static final int TYPE_DVB_H = 131840; // 0x20300
+ field public static final int TYPE_DVB_S = 131328; // 0x20100
+ field public static final int TYPE_DVB_S2 = 131329; // 0x20101
+ field public static final int TYPE_DVB_SH = 132096; // 0x20400
+ field public static final int TYPE_DVB_T = 131072; // 0x20000
+ field public static final int TYPE_DVB_T2 = 131073; // 0x20001
+ field public static final int TYPE_ISDB_C = 262912; // 0x40300
+ field public static final int TYPE_ISDB_S = 262656; // 0x40200
+ field public static final int TYPE_ISDB_T = 262144; // 0x40000
+ field public static final int TYPE_ISDB_TB = 262400; // 0x40100
+ field public static final int TYPE_OTHER = 0; // 0x0
+ field public static final int TYPE_PASSTHROUGH = 65536; // 0x10000
+ field public static final int TYPE_S_DMB = 393472; // 0x60100
+ field public static final int TYPE_T_DMB = 393216; // 0x60000
+ }
+
+ public static final class TvContract.Programs implements android.media.tv.TvContract.BaseTvColumns {
+ field public static final java.lang.String COLUMN_AUDIO_LANGUAGE = "audio_language";
+ field public static final java.lang.String COLUMN_CHANNEL_ID = "channel_id";
+ field public static final java.lang.String COLUMN_DATA = "data";
+ field public static final java.lang.String COLUMN_DESCRIPTION = "description";
+ field public static final java.lang.String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis";
+ field public static final java.lang.String COLUMN_GENRE = "genre";
+ field public static final java.lang.String COLUMN_LONG_DESCRIPTION = "long_description";
+ field public static final java.lang.String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis";
+ field public static final java.lang.String COLUMN_TITLE = "title";
+ field public static final java.lang.String COLUMN_VERSION_NUMBER = "version_number";
+ field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.com.android.tv.programs";
+ field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.com.android.tv.programs";
+ field public static final android.net.Uri CONTENT_URI;
+ }
+
+ public final class TvInputInfo implements android.os.Parcelable {
+ method public int describeContents();
+ method public android.content.ComponentName getComponent();
+ method public java.lang.String getId();
+ method public java.lang.String getPackageName();
+ method public java.lang.String getServiceName();
+ method public java.lang.CharSequence loadLabel(android.content.pm.PackageManager);
+ method public void writeToParcel(android.os.Parcel, int);
+ }
+
+ public final class TvInputManager {
+ method public void createSession(java.lang.String, android.media.tv.TvInputManager.SessionCallback, android.os.Handler);
+ method public boolean getAvailability(java.lang.String);
+ method public java.util.List<android.media.tv.TvInputInfo> getTvInputList();
+ method public void registerListener(java.lang.String, android.media.tv.TvInputManager.TvInputListener, android.os.Handler);
+ method public void unregisterListener(java.lang.String, android.media.tv.TvInputManager.TvInputListener);
+ }
+
+ public static final class TvInputManager.Session {
+ method public void release();
+ method public void setVolume(float);
+ method public void tune(android.net.Uri);
+ }
+
+ public static abstract class TvInputManager.SessionCallback {
+ ctor public TvInputManager.SessionCallback();
+ method public void onSessionCreated(android.media.tv.TvInputManager.Session);
+ method public void onSessionReleased(android.media.tv.TvInputManager.Session);
+ }
+
+ public static abstract class TvInputManager.TvInputListener {
+ ctor public TvInputManager.TvInputListener();
+ method public void onAvailabilityChanged(java.lang.String, boolean);
+ }
+
+ public abstract class TvInputService extends android.app.Service {
+ ctor public TvInputService();
+ method public final android.os.IBinder onBind(android.content.Intent);
+ method public abstract android.media.tv.TvInputService.TvInputSessionImpl onCreateSession();
+ method public final void setAvailable(boolean);
+ field public static final java.lang.String SERVICE_INTERFACE = "android.media.tv.TvInputService";
+ }
+
+ public abstract class TvInputService.TvInputSessionImpl implements android.view.KeyEvent.Callback {
+ ctor public TvInputService.TvInputSessionImpl();
+ method public android.view.View onCreateOverlayView();
+ method public boolean onGenericMotionEvent(android.view.MotionEvent);
+ method public boolean onKeyDown(int, android.view.KeyEvent);
+ method public boolean onKeyLongPress(int, android.view.KeyEvent);
+ method public boolean onKeyMultiple(int, int, android.view.KeyEvent);
+ method public boolean onKeyUp(int, android.view.KeyEvent);
+ method public abstract void onRelease();
+ method public abstract boolean onSetSurface(android.view.Surface);
+ method public abstract void onSetVolume(float);
+ method public boolean onTouchEvent(android.view.MotionEvent);
+ method public boolean onTrackballEvent(android.view.MotionEvent);
+ method public abstract boolean onTune(android.net.Uri);
+ method public void setOverlayViewEnabled(boolean);
+ }
+
+ public class TvView extends android.view.SurfaceView {
+ ctor public TvView(android.content.Context);
+ ctor public TvView(android.content.Context, android.util.AttributeSet);
+ ctor public TvView(android.content.Context, android.util.AttributeSet, int);
+ method public void bindTvInput(java.lang.String, android.media.tv.TvInputManager.SessionCallback);
+ method public boolean dispatchUnhandledInputEvent(android.view.InputEvent);
+ method public boolean onUnhandledInputEvent(android.view.InputEvent);
+ method public void setOnUnhandledInputEventListener(android.media.tv.TvView.OnUnhandledInputEventListener);
+ method public void unbindTvInput();
+ }
+
+ public static abstract interface TvView.OnUnhandledInputEventListener {
+ method public abstract boolean onUnhandledInputEvent(android.view.InputEvent);
+ }
+
+}
+
package android.mtp {
public final class MtpConstants {
@@ -24946,81 +25100,6 @@
field public static final java.lang.String TYPE = "type";
}
- public final class TvContract {
- method public static final android.net.Uri buildChannelUri(long);
- method public static final android.net.Uri buildChannelsUriForInput(android.content.ComponentName);
- method public static final android.net.Uri buildChannelsUriForInput(android.content.ComponentName, boolean);
- method public static final android.net.Uri buildProgramUri(long);
- method public static final android.net.Uri buildProgramsUriForChannel(android.net.Uri);
- method public static final android.net.Uri buildProgramsUriForChannel(android.net.Uri, long, long);
- field public static final java.lang.String AUTHORITY = "com.android.tv";
- }
-
- public static abstract interface TvContract.BaseTvColumns implements android.provider.BaseColumns {
- field public static final java.lang.String COLUMN_PACKAGE_NAME = "package_name";
- }
-
- public static final class TvContract.Channels implements android.provider.TvContract.BaseTvColumns {
- field public static final java.lang.String COLUMN_BROWSABLE = "browsable";
- field public static final java.lang.String COLUMN_DATA = "data";
- field public static final java.lang.String COLUMN_DESCRIPTION = "description";
- field public static final java.lang.String COLUMN_DISPLAY_NAME = "display_name";
- field public static final java.lang.String COLUMN_DISPLAY_NUMBER = "display_number";
- field public static final java.lang.String COLUMN_LOCKED = "locked";
- field public static final java.lang.String COLUMN_ORIGINAL_NETWORK_ID = "original_network_id";
- field public static final java.lang.String COLUMN_SEARCHABLE = "searchable";
- field public static final java.lang.String COLUMN_SERVICE_ID = "service_id";
- field public static final java.lang.String COLUMN_SERVICE_NAME = "service_name";
- field public static final java.lang.String COLUMN_SERVICE_TYPE = "service_type";
- field public static final java.lang.String COLUMN_TRANSPORT_STREAM_ID = "transport_stream_id";
- field public static final java.lang.String COLUMN_TYPE = "type";
- field public static final java.lang.String COLUMN_VERSION_NUMBER = "version_number";
- field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.com.android.tv.channels";
- field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.com.android.tv.channels";
- field public static final android.net.Uri CONTENT_URI;
- field public static final int SERVICE_TYPE_OTHER = 0; // 0x0
- field public static final int SERVICE_TYPE_RADIO = 2; // 0x2
- field public static final int SERVICE_TYPE_TV = 1; // 0x1
- field public static final int TYPE_1SEG = 263168; // 0x40400
- field public static final int TYPE_ATSC_C = 197120; // 0x30200
- field public static final int TYPE_ATSC_M_H = 197120; // 0x30200
- field public static final int TYPE_ATSC_T = 196608; // 0x30000
- field public static final int TYPE_CMMB = 327936; // 0x50100
- field public static final int TYPE_DTMB = 327680; // 0x50000
- field public static final int TYPE_DVB_C = 131584; // 0x20200
- field public static final int TYPE_DVB_C2 = 131585; // 0x20201
- field public static final int TYPE_DVB_H = 131840; // 0x20300
- field public static final int TYPE_DVB_S = 131328; // 0x20100
- field public static final int TYPE_DVB_S2 = 131329; // 0x20101
- field public static final int TYPE_DVB_SH = 132096; // 0x20400
- field public static final int TYPE_DVB_T = 131072; // 0x20000
- field public static final int TYPE_DVB_T2 = 131073; // 0x20001
- field public static final int TYPE_ISDB_C = 262912; // 0x40300
- field public static final int TYPE_ISDB_S = 262656; // 0x40200
- field public static final int TYPE_ISDB_T = 262144; // 0x40000
- field public static final int TYPE_ISDB_TB = 262400; // 0x40100
- field public static final int TYPE_OTHER = 0; // 0x0
- field public static final int TYPE_PASSTHROUGH = 65536; // 0x10000
- field public static final int TYPE_S_DMB = 393472; // 0x60100
- field public static final int TYPE_T_DMB = 393216; // 0x60000
- }
-
- public static final class TvContract.Programs implements android.provider.TvContract.BaseTvColumns {
- field public static final java.lang.String COLUMN_AUDIO_LANGUAGE = "audio_language";
- field public static final java.lang.String COLUMN_CHANNEL_ID = "channel_id";
- field public static final java.lang.String COLUMN_DATA = "data";
- field public static final java.lang.String COLUMN_DESCRIPTION = "description";
- field public static final java.lang.String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis";
- field public static final java.lang.String COLUMN_GENRE = "genre";
- field public static final java.lang.String COLUMN_LONG_DESCRIPTION = "long_description";
- field public static final java.lang.String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis";
- field public static final java.lang.String COLUMN_TITLE = "title";
- field public static final java.lang.String COLUMN_VERSION_NUMBER = "version_number";
- field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.com.android.tv.programs";
- field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.com.android.tv.programs";
- field public static final android.net.Uri CONTENT_URI;
- }
-
public class UserDictionary {
ctor public UserDictionary();
field public static final java.lang.String AUTHORITY = "user_dictionary";
@@ -30594,85 +30673,6 @@
}
-package android.tv {
-
- public final class TvInputInfo implements android.os.Parcelable {
- method public int describeContents();
- method public android.content.ComponentName getComponent();
- method public java.lang.String getId();
- method public java.lang.String getPackageName();
- method public java.lang.String getServiceName();
- method public java.lang.CharSequence loadLabel(android.content.pm.PackageManager);
- method public void writeToParcel(android.os.Parcel, int);
- }
-
- public final class TvInputManager {
- method public void createSession(java.lang.String, android.tv.TvInputManager.SessionCallback, android.os.Handler);
- method public boolean getAvailability(java.lang.String);
- method public java.util.List<android.tv.TvInputInfo> getTvInputList();
- method public void registerListener(java.lang.String, android.tv.TvInputManager.TvInputListener, android.os.Handler);
- method public void unregisterListener(java.lang.String, android.tv.TvInputManager.TvInputListener);
- }
-
- public static final class TvInputManager.Session {
- method public void release();
- method public void setVolume(float);
- method public void tune(android.net.Uri);
- }
-
- public static abstract class TvInputManager.SessionCallback {
- ctor public TvInputManager.SessionCallback();
- method public void onSessionCreated(android.tv.TvInputManager.Session);
- method public void onSessionReleased(android.tv.TvInputManager.Session);
- }
-
- public static abstract class TvInputManager.TvInputListener {
- ctor public TvInputManager.TvInputListener();
- method public void onAvailabilityChanged(java.lang.String, boolean);
- }
-
- public abstract class TvInputService extends android.app.Service {
- ctor public TvInputService();
- method public final android.os.IBinder onBind(android.content.Intent);
- method public abstract android.tv.TvInputService.TvInputSessionImpl onCreateSession();
- method public final void setAvailable(boolean);
- field public static final java.lang.String SERVICE_INTERFACE = "android.tv.TvInputService";
- }
-
- public abstract class TvInputService.TvInputSessionImpl implements android.view.KeyEvent.Callback {
- ctor public TvInputService.TvInputSessionImpl();
- method public android.view.View onCreateOverlayView();
- method public boolean onGenericMotionEvent(android.view.MotionEvent);
- method public boolean onKeyDown(int, android.view.KeyEvent);
- method public boolean onKeyLongPress(int, android.view.KeyEvent);
- method public boolean onKeyMultiple(int, int, android.view.KeyEvent);
- method public boolean onKeyUp(int, android.view.KeyEvent);
- method public abstract void onRelease();
- method public abstract boolean onSetSurface(android.view.Surface);
- method public abstract void onSetVolume(float);
- method public boolean onTouchEvent(android.view.MotionEvent);
- method public boolean onTrackballEvent(android.view.MotionEvent);
- method public abstract boolean onTune(android.net.Uri);
- method public void setOverlayViewEnabled(boolean);
- }
-
- public class TvView extends android.view.SurfaceView {
- ctor public TvView(android.content.Context);
- ctor public TvView(android.content.Context, android.util.AttributeSet);
- ctor public TvView(android.content.Context, android.util.AttributeSet, int);
- method public void bindTvInput(java.lang.String, android.tv.TvInputManager.SessionCallback);
- method public boolean dispatchUnhandledInputEvent(android.view.InputEvent);
- method public boolean onUnhandledInputEvent(android.view.InputEvent);
- method public void setOnUnhandledInputEventListener(android.tv.TvView.OnUnhandledInputEventListener);
- method public void unbindTvInput();
- }
-
- public static abstract interface TvView.OnUnhandledInputEventListener {
- method public abstract boolean onUnhandledInputEvent(android.view.InputEvent);
- }
-
-}
-
package android.util {
public class AndroidException extends java.lang.Exception {
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index b7c2c22..47047b8 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -39,6 +39,7 @@
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.net.Uri;
+import android.os.Build;
import android.os.Bundle;
import android.os.IUserManager;
import android.os.Process;
@@ -57,7 +58,6 @@
import java.util.Comparator;
import java.util.List;
import java.util.WeakHashMap;
-
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
@@ -823,6 +823,7 @@
byte[] tag = null;
String originatingUriString = null;
String referrer = null;
+ String abi = null;
while ((opt=nextOption()) != null) {
if (opt.equals("-l")) {
@@ -893,12 +894,34 @@
System.err.println("Error: must supply argument for --referrer");
return;
}
+ } else if (opt.equals("--abi")) {
+ abi = nextOptionData();
+ if (abi == null) {
+ System.err.println("Error: must supply argument for --abi");
+ return;
+ }
} else {
System.err.println("Error: Unknown option: " + opt);
return;
}
}
+ if (abi != null) {
+ final String[] supportedAbis = Build.SUPPORTED_ABIS;
+ boolean matched = false;
+ for (String supportedAbi : supportedAbis) {
+ if (supportedAbi.equals(abi)) {
+ matched = true;
+ break;
+ }
+ }
+
+ if (!matched) {
+ System.err.println("Error: abi " + abi + " not supported on this device.");
+ return;
+ }
+ }
+
final ContainerEncryptionParams encryptionParams;
if (algo != null || iv != null || key != null || macAlgo != null || macKey != null
|| tag != null) {
@@ -976,8 +999,9 @@
VerificationParams verificationParams = new VerificationParams(verificationURI,
originatingURI, referrerURI, VerificationParams.NO_UID, null);
- mPm.installPackageWithVerificationAndEncryptionEtc(apkURI, null, obs, installFlags,
- installerPackageName, verificationParams, encryptionParams);
+ mPm.installPackageWithVerificationEncryptionAndAbiOverrideEtc(apkURI, null,
+ obs, installFlags, installerPackageName, verificationParams,
+ encryptionParams, abi);
synchronized (obs) {
while (!obs.finished) {
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 4f335bb..e03224c 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -75,6 +75,8 @@
import android.media.AudioManager;
import android.media.MediaRouter;
import android.media.session.MediaSessionManager;
+import android.media.tv.ITvInputManager;
+import android.media.tv.TvInputManager;
import android.net.ConnectivityManager;
import android.net.IConnectivityManager;
import android.net.EthernetManager;
@@ -119,8 +121,6 @@
import android.service.fingerprint.FingerprintManagerReceiver;
import android.service.fingerprint.FingerprintService;
import android.telephony.TelephonyManager;
-import android.tv.ITvInputManager;
-import android.tv.TvInputManager;
import android.content.ClipboardManager;
import android.util.AndroidRuntimeException;
import android.util.ArrayMap;
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index c69e669..a040efb 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2751,11 +2751,11 @@
/**
* Use with {@link #getSystemService} to retrieve a
- * {@link android.tv.TvInputManager} for interacting with TV inputs on the
- * device.
+ * {@link android.media.tv.TvInputManager} for interacting with TV inputs
+ * on the device.
*
* @see #getSystemService
- * @see android.tv.TvInputManager
+ * @see android.media.tv.TvInputManager
*/
public static final String TV_INPUT_SERVICE = "tv_input";
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 44a6a5d..70668e1 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -433,6 +433,13 @@
in VerificationParams verificationParams,
in ContainerEncryptionParams encryptionParams);
+ void installPackageWithVerificationEncryptionAndAbiOverrideEtc(in Uri packageURI,
+ in IPackageInstallObserver observer, in IPackageInstallObserver2 observer2,
+ int flags, in String installerPackageName,
+ in VerificationParams verificationParams,
+ in ContainerEncryptionParams encryptionParams,
+ in String packageAbiOverride);
+
int installExistingPackageAsUser(String packageName, int userId);
void verifyPendingInstall(int id, int verificationCode);
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 24844ba..a48a388 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -905,7 +905,7 @@
return null;
}
- private int networkTypeForNetworkCapabilities(NetworkCapabilities netCap) {
+ private int legacyTypeForNetworkCapabilities(NetworkCapabilities netCap) {
if (netCap == null) return TYPE_NONE;
if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) {
return TYPE_MOBILE_CBS;
@@ -928,6 +928,9 @@
if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
return TYPE_MOBILE_HIPRI;
}
+ if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_WIFI_P2P)) {
+ return TYPE_WIFI_P2P;
+ }
return TYPE_NONE;
}
@@ -988,7 +991,7 @@
private NetworkRequest requestNetworkForFeatureLocked(NetworkCapabilities netCap) {
int delay = -1;
- int type = networkTypeForNetworkCapabilities(netCap);
+ int type = legacyTypeForNetworkCapabilities(netCap);
try {
delay = mService.getRestoreDefaultNetworkDelay(type);
} catch (RemoteException e) {}
@@ -997,7 +1000,7 @@
l.delay = delay;
l.expireSequenceNumber = 0;
l.networkRequest = sendRequestForNetwork(netCap, l.networkCallbackListener, 0,
- REQUEST, true);
+ REQUEST, type);
if (l.networkRequest == null) return null;
sLegacyRequests.put(netCap, l);
sendExpireMsgForFeature(netCap, l.expireSequenceNumber, delay);
@@ -2144,7 +2147,7 @@
private NetworkRequest sendRequestForNetwork(NetworkCapabilities need,
NetworkCallbackListener networkCallbackListener, int timeoutSec, int action,
- boolean legacy) {
+ int legacyType) {
NetworkRequest networkRequest = null;
if (networkCallbackListener == null) {
throw new IllegalArgumentException("null NetworkCallbackListener");
@@ -2157,7 +2160,7 @@
new Binder());
} else {
networkRequest = mService.requestNetwork(need, new Messenger(sCallbackHandler),
- timeoutSec, new Binder(), legacy);
+ timeoutSec, new Binder(), legacyType);
}
if (networkRequest != null) {
synchronized(sNetworkCallbackListener) {
@@ -2187,7 +2190,7 @@
*/
public NetworkRequest requestNetwork(NetworkCapabilities need,
NetworkCallbackListener networkCallbackListener) {
- return sendRequestForNetwork(need, networkCallbackListener, 0, REQUEST, false);
+ return sendRequestForNetwork(need, networkCallbackListener, 0, REQUEST, TYPE_NONE);
}
/**
@@ -2210,7 +2213,8 @@
*/
public NetworkRequest requestNetwork(NetworkCapabilities need,
NetworkCallbackListener networkCallbackListener, int timeoutSec) {
- return sendRequestForNetwork(need, networkCallbackListener, timeoutSec, REQUEST, false);
+ return sendRequestForNetwork(need, networkCallbackListener, timeoutSec, REQUEST,
+ TYPE_NONE);
}
/**
@@ -2288,7 +2292,7 @@
*/
public NetworkRequest listenForNetwork(NetworkCapabilities need,
NetworkCallbackListener networkCallbackListener) {
- return sendRequestForNetwork(need, networkCallbackListener, 0, LISTEN, false);
+ return sendRequestForNetwork(need, networkCallbackListener, 0, LISTEN, TYPE_NONE);
}
/**
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index b67ae88..5f1ff3e 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -158,7 +158,7 @@
in NetworkCapabilities nc, int score);
NetworkRequest requestNetwork(in NetworkCapabilities networkCapabilities,
- in Messenger messenger, int timeoutSec, in IBinder binder, boolean legacy);
+ in Messenger messenger, int timeoutSec, in IBinder binder, int legacy);
NetworkRequest pendingRequestForNetwork(in NetworkCapabilities networkCapabilities,
in PendingIntent operation);
diff --git a/core/java/android/net/NetworkInfo.java b/core/java/android/net/NetworkInfo.java
index ccc56e2..d279412 100644
--- a/core/java/android/net/NetworkInfo.java
+++ b/core/java/android/net/NetworkInfo.java
@@ -188,6 +188,15 @@
}
/**
+ * @hide
+ */
+ public void setType(int type) {
+ synchronized (this) {
+ mNetworkType = type;
+ }
+ }
+
+ /**
* Return a network-type-specific integer describing the subtype
* of the network.
* @return the network subtype
diff --git a/core/java/android/net/NetworkRequest.java b/core/java/android/net/NetworkRequest.java
index 480cb057..47377e9 100644
--- a/core/java/android/net/NetworkRequest.java
+++ b/core/java/android/net/NetworkRequest.java
@@ -47,19 +47,19 @@
public final int requestId;
/**
- * Set for legacy requests and the default.
+ * Set for legacy requests and the default. Set to TYPE_NONE for none.
* Causes CONNECTIVITY_ACTION broadcasts to be sent.
* @hide
*/
- public final boolean needsBroadcasts;
+ public final int legacyType;
/**
* @hide
*/
- public NetworkRequest(NetworkCapabilities nc, boolean needsBroadcasts, int rId) {
+ public NetworkRequest(NetworkCapabilities nc, int legacyType, int rId) {
requestId = rId;
networkCapabilities = nc;
- this.needsBroadcasts = needsBroadcasts;
+ this.legacyType = legacyType;
}
/**
@@ -68,7 +68,7 @@
public NetworkRequest(NetworkRequest that) {
networkCapabilities = new NetworkCapabilities(that.networkCapabilities);
requestId = that.requestId;
- needsBroadcasts = that.needsBroadcasts;
+ this.legacyType = that.legacyType;
}
// implement the Parcelable interface
@@ -77,16 +77,16 @@
}
public void writeToParcel(Parcel dest, int flags) {
dest.writeParcelable(networkCapabilities, flags);
- dest.writeInt(needsBroadcasts ? 1 : 0);
+ dest.writeInt(legacyType);
dest.writeInt(requestId);
}
public static final Creator<NetworkRequest> CREATOR =
new Creator<NetworkRequest>() {
public NetworkRequest createFromParcel(Parcel in) {
NetworkCapabilities nc = (NetworkCapabilities)in.readParcelable(null);
- boolean needsBroadcasts = (in.readInt() == 1);
+ int legacyType = in.readInt();
int requestId = in.readInt();
- NetworkRequest result = new NetworkRequest(nc, needsBroadcasts, requestId);
+ NetworkRequest result = new NetworkRequest(nc, legacyType, requestId);
return result;
}
public NetworkRequest[] newArray(int size) {
@@ -95,14 +95,14 @@
};
public String toString() {
- return "NetworkRequest [ id=" + requestId + ", needsBroadcasts=" + needsBroadcasts +
+ return "NetworkRequest [ id=" + requestId + ", legacyType=" + legacyType +
", " + networkCapabilities.toString() + " ]";
}
public boolean equals(Object obj) {
if (obj instanceof NetworkRequest == false) return false;
NetworkRequest that = (NetworkRequest)obj;
- return (that.needsBroadcasts == this.needsBroadcasts &&
+ return (that.legacyType == this.legacyType &&
that.requestId == this.requestId &&
((that.networkCapabilities == null && this.networkCapabilities == null) ||
(that.networkCapabilities != null &&
@@ -110,7 +110,7 @@
}
public int hashCode() {
- return requestId + (needsBroadcasts ? 1013 : 2026) +
+ return requestId + (legacyType * 1013) +
(networkCapabilities.hashCode() * 1051);
}
}
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index 424d860..5056097 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -75,22 +75,10 @@
// Constructors
///////////////////////////////////////////////////////////////////////////
- /**
- * Creates a canvas to render directly on screen.
- */
- GLES20Canvas(boolean translucent) {
- this(false, translucent);
- }
-
- protected GLES20Canvas(boolean record, boolean translucent) {
- mOpaque = !translucent;
-
- if (record) {
- mRenderer = nCreateDisplayListRenderer();
- } else {
- mRenderer = nCreateRenderer();
- }
-
+ // TODO: Merge with GLES20RecordingCanvas
+ protected GLES20Canvas() {
+ mOpaque = false;
+ mRenderer = nCreateDisplayListRenderer();
setupFinalizer();
}
@@ -102,7 +90,6 @@
}
}
- private static native long nCreateRenderer();
private static native long nCreateDisplayListRenderer();
private static native void nResetDisplayListRenderer(long renderer);
private static native void nDestroyRenderer(long renderer);
@@ -131,36 +118,6 @@
private static native void nSetProperty(String name, String value);
///////////////////////////////////////////////////////////////////////////
- // Hardware layers
- ///////////////////////////////////////////////////////////////////////////
-
- @Override
- void pushLayerUpdate(HardwareLayer layer) {
- nPushLayerUpdate(mRenderer, layer.getLayer());
- }
-
- @Override
- void cancelLayerUpdate(HardwareLayer layer) {
- nCancelLayerUpdate(mRenderer, layer.getLayer());
- }
-
- @Override
- void flushLayerUpdates() {
- nFlushLayerUpdates(mRenderer);
- }
-
- @Override
- void clearLayerUpdates() {
- nClearLayerUpdates(mRenderer);
- }
-
- static native boolean nCopyLayer(long layerId, long bitmap);
- private static native void nClearLayerUpdates(long renderer);
- private static native void nFlushLayerUpdates(long renderer);
- private static native void nPushLayerUpdate(long renderer, long layer);
- private static native void nCancelLayerUpdate(long renderer, long layer);
-
- ///////////////////////////////////////////////////////////////////////////
// Canvas management
///////////////////////////////////////////////////////////////////////////
@@ -234,20 +191,6 @@
private static native void nFinish(long renderer);
- /**
- * Returns the size of the stencil buffer required by the underlying
- * implementation.
- *
- * @return The minimum number of bits the stencil buffer must. Always >= 0.
- *
- * @hide
- */
- public static int getStencilSize() {
- return nGetStencilSize();
- }
-
- private static native int nGetStencilSize();
-
///////////////////////////////////////////////////////////////////////////
// Functor
///////////////////////////////////////////////////////////////////////////
@@ -284,49 +227,6 @@
*/
static final int FLUSH_CACHES_FULL = 2;
- /**
- * Flush caches to reclaim as much memory as possible. The amount of memory
- * to reclaim is indicate by the level parameter.
- *
- * The level can be one of {@link #FLUSH_CACHES_MODERATE} or
- * {@link #FLUSH_CACHES_FULL}.
- *
- * @param level Hint about the amount of memory to reclaim
- */
- static void flushCaches(int level) {
- nFlushCaches(level);
- }
-
- private static native void nFlushCaches(int level);
-
- /**
- * Release all resources associated with the underlying caches. This should
- * only be called after a full flushCaches().
- *
- * @hide
- */
- static void terminateCaches() {
- nTerminateCaches();
- }
-
- private static native void nTerminateCaches();
-
- static boolean initCaches() {
- return nInitCaches();
- }
-
- private static native boolean nInitCaches();
-
- ///////////////////////////////////////////////////////////////////////////
- // Atlas
- ///////////////////////////////////////////////////////////////////////////
-
- static void initAtlas(GraphicBuffer buffer, long[] map) {
- nInitAtlas(buffer, map, map.length);
- }
-
- private static native void nInitAtlas(GraphicBuffer buffer, long[] map, int count);
-
///////////////////////////////////////////////////////////////////////////
// Display list
///////////////////////////////////////////////////////////////////////////
@@ -899,12 +799,6 @@
private static native void nDrawPath(long renderer, long path, long paint);
private static native void nDrawRects(long renderer, long region, long paint);
- void drawRects(float[] rects, int count, Paint paint) {
- nDrawRects(mRenderer, rects, count, paint.mNativePaint);
- }
-
- private static native void nDrawRects(long renderer, float[] rects, int count, long paint);
-
@Override
public void drawPicture(Picture picture) {
if (picture.createdFromStream) {
diff --git a/core/java/android/view/GLES20RecordingCanvas.java b/core/java/android/view/GLES20RecordingCanvas.java
index a94ec3a..b2961e5 100644
--- a/core/java/android/view/GLES20RecordingCanvas.java
+++ b/core/java/android/view/GLES20RecordingCanvas.java
@@ -36,7 +36,7 @@
RenderNode mNode;
private GLES20RecordingCanvas() {
- super(true, true);
+ super();
}
static GLES20RecordingCanvas obtain(@NonNull RenderNode node) {
diff --git a/core/java/android/view/GLRenderer.java b/core/java/android/view/GLRenderer.java
deleted file mode 100644
index f1163e2..0000000
--- a/core/java/android/view/GLRenderer.java
+++ /dev/null
@@ -1,1521 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import static javax.microedition.khronos.egl.EGL10.EGL_ALPHA_SIZE;
-import static javax.microedition.khronos.egl.EGL10.EGL_BAD_NATIVE_WINDOW;
-import static javax.microedition.khronos.egl.EGL10.EGL_BLUE_SIZE;
-import static javax.microedition.khronos.egl.EGL10.EGL_CONFIG_CAVEAT;
-import static javax.microedition.khronos.egl.EGL10.EGL_DEFAULT_DISPLAY;
-import static javax.microedition.khronos.egl.EGL10.EGL_DEPTH_SIZE;
-import static javax.microedition.khronos.egl.EGL10.EGL_DRAW;
-import static javax.microedition.khronos.egl.EGL10.EGL_GREEN_SIZE;
-import static javax.microedition.khronos.egl.EGL10.EGL_HEIGHT;
-import static javax.microedition.khronos.egl.EGL10.EGL_NONE;
-import static javax.microedition.khronos.egl.EGL10.EGL_NO_CONTEXT;
-import static javax.microedition.khronos.egl.EGL10.EGL_NO_DISPLAY;
-import static javax.microedition.khronos.egl.EGL10.EGL_NO_SURFACE;
-import static javax.microedition.khronos.egl.EGL10.EGL_RED_SIZE;
-import static javax.microedition.khronos.egl.EGL10.EGL_RENDERABLE_TYPE;
-import static javax.microedition.khronos.egl.EGL10.EGL_SAMPLES;
-import static javax.microedition.khronos.egl.EGL10.EGL_SAMPLE_BUFFERS;
-import static javax.microedition.khronos.egl.EGL10.EGL_STENCIL_SIZE;
-import static javax.microedition.khronos.egl.EGL10.EGL_SUCCESS;
-import static javax.microedition.khronos.egl.EGL10.EGL_SURFACE_TYPE;
-import static javax.microedition.khronos.egl.EGL10.EGL_WIDTH;
-import static javax.microedition.khronos.egl.EGL10.EGL_WINDOW_BIT;
-
-import android.content.ComponentCallbacks2;
-import android.graphics.Bitmap;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.graphics.SurfaceTexture;
-import android.opengl.EGL14;
-import android.opengl.GLUtils;
-import android.opengl.ManagedEGLContext;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.os.Trace;
-import android.util.DisplayMetrics;
-import android.util.Log;
-import android.view.Surface.OutOfResourcesException;
-
-import com.google.android.gles_jni.EGLImpl;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.locks.ReentrantLock;
-
-import javax.microedition.khronos.egl.EGL10;
-import javax.microedition.khronos.egl.EGL11;
-import javax.microedition.khronos.egl.EGLConfig;
-import javax.microedition.khronos.egl.EGLContext;
-import javax.microedition.khronos.egl.EGLDisplay;
-import javax.microedition.khronos.egl.EGLSurface;
-import javax.microedition.khronos.opengles.GL;
-
-/**
- * Hardware renderer using OpenGL
- *
- * @hide
- */
-public class GLRenderer extends HardwareRenderer {
- static final int SURFACE_STATE_ERROR = 0;
- static final int SURFACE_STATE_SUCCESS = 1;
- static final int SURFACE_STATE_UPDATED = 2;
-
- static final int FUNCTOR_PROCESS_DELAY = 4;
-
- /**
- * Number of frames to profile.
- */
- private static final int PROFILE_MAX_FRAMES = 128;
-
- /**
- * Number of floats per profiled frame.
- */
- private static final int PROFILE_FRAME_DATA_COUNT = 3;
-
- private static final int PROFILE_DRAW_MARGIN = 0;
- private static final int PROFILE_DRAW_WIDTH = 3;
- private static final int[] PROFILE_DRAW_COLORS = { 0xcf3e66cc, 0xcfdc3912, 0xcfe69800 };
- private static final int PROFILE_DRAW_CURRENT_FRAME_COLOR = 0xcf5faa4d;
- private static final int PROFILE_DRAW_THRESHOLD_COLOR = 0xff5faa4d;
- private static final int PROFILE_DRAW_THRESHOLD_STROKE_WIDTH = 2;
- private static final int PROFILE_DRAW_DP_PER_MS = 7;
-
- private static final String[] VISUALIZERS = {
- PROFILE_PROPERTY_VISUALIZE_BARS,
- };
-
- private static final String[] OVERDRAW = {
- OVERDRAW_PROPERTY_SHOW,
- };
- private static final int GL_VERSION = 2;
-
- static EGL10 sEgl;
- static EGLDisplay sEglDisplay;
- static EGLConfig sEglConfig;
- static final Object[] sEglLock = new Object[0];
- int mWidth = -1, mHeight = -1;
-
- static final ThreadLocal<ManagedEGLContext> sEglContextStorage
- = new ThreadLocal<ManagedEGLContext>();
-
- EGLContext mEglContext;
- Thread mEglThread;
-
- EGLSurface mEglSurface;
-
- GL mGl;
- HardwareCanvas mCanvas;
-
- String mName;
-
- long mFrameCount;
- Paint mDebugPaint;
-
- static boolean sDirtyRegions;
- static final boolean sDirtyRegionsRequested;
- static {
- String dirtyProperty = SystemProperties.get(RENDER_DIRTY_REGIONS_PROPERTY, "true");
- //noinspection PointlessBooleanExpression,ConstantConditions
- sDirtyRegions = "true".equalsIgnoreCase(dirtyProperty);
- sDirtyRegionsRequested = sDirtyRegions;
- }
-
- boolean mDirtyRegionsEnabled;
- boolean mUpdateDirtyRegions;
-
- boolean mProfileEnabled;
- int mProfileVisualizerType = -1;
- float[] mProfileData;
- ReentrantLock mProfileLock;
- int mProfileCurrentFrame = -PROFILE_FRAME_DATA_COUNT;
-
- GraphDataProvider mDebugDataProvider;
- float[][] mProfileShapes;
- Paint mProfilePaint;
-
- boolean mDebugDirtyRegions;
- int mDebugOverdraw = -1;
-
- final boolean mTranslucent;
-
- private boolean mDestroyed;
-
- private final Rect mRedrawClip = new Rect();
-
- private final int[] mSurfaceSize = new int[2];
-
- private long mDrawDelta = Long.MAX_VALUE;
-
- private GLES20Canvas mGlCanvas;
-
- private DisplayMetrics mDisplayMetrics;
-
- private static EGLSurface sPbuffer;
- private static final Object[] sPbufferLock = new Object[0];
-
- private List<HardwareLayer> mLayerUpdates = new ArrayList<HardwareLayer>();
-
- private static class GLRendererEglContext extends ManagedEGLContext {
- final Handler mHandler = new Handler();
-
- public GLRendererEglContext(EGLContext context) {
- super(context);
- }
-
- @Override
- public void onTerminate(final EGLContext eglContext) {
- // Make sure we do this on the correct thread.
- if (mHandler.getLooper() != Looper.myLooper()) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- onTerminate(eglContext);
- }
- });
- return;
- }
-
- synchronized (sEglLock) {
- if (sEgl == null) return;
-
- if (EGLImpl.getInitCount(sEglDisplay) == 1) {
- usePbufferSurface(eglContext);
- GLES20Canvas.terminateCaches();
-
- sEgl.eglDestroyContext(sEglDisplay, eglContext);
- sEglContextStorage.set(null);
- sEglContextStorage.remove();
-
- sEgl.eglDestroySurface(sEglDisplay, sPbuffer);
- sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE,
- EGL_NO_SURFACE, EGL_NO_CONTEXT);
-
- sEgl.eglReleaseThread();
- sEgl.eglTerminate(sEglDisplay);
-
- sEgl = null;
- sEglDisplay = null;
- sEglConfig = null;
- sPbuffer = null;
- }
- }
- }
- }
-
- HardwareCanvas createCanvas() {
- return mGlCanvas = new GLES20Canvas(mTranslucent);
- }
-
- ManagedEGLContext createManagedContext(EGLContext eglContext) {
- return new GLRendererEglContext(mEglContext);
- }
-
- int[] getConfig(boolean dirtyRegions) {
- //noinspection PointlessBooleanExpression,ConstantConditions
- final int stencilSize = GLES20Canvas.getStencilSize();
- final int swapBehavior = dirtyRegions ? EGL14.EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0;
-
- return new int[] {
- EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT,
- EGL_RED_SIZE, 8,
- EGL_GREEN_SIZE, 8,
- EGL_BLUE_SIZE, 8,
- EGL_ALPHA_SIZE, 8,
- EGL_DEPTH_SIZE, 0,
- EGL_CONFIG_CAVEAT, EGL_NONE,
- EGL_STENCIL_SIZE, stencilSize,
- EGL_SURFACE_TYPE, EGL_WINDOW_BIT | swapBehavior,
- EGL_NONE
- };
- }
-
- void initCaches() {
- if (GLES20Canvas.initCaches()) {
- // Caches were (re)initialized, rebind atlas
- initAtlas();
- }
- }
-
- void initAtlas() {
- IBinder binder = ServiceManager.getService("assetatlas");
- if (binder == null) return;
-
- IAssetAtlas atlas = IAssetAtlas.Stub.asInterface(binder);
- try {
- if (atlas.isCompatible(android.os.Process.myPpid())) {
- GraphicBuffer buffer = atlas.getBuffer();
- if (buffer != null) {
- long[] map = atlas.getMap();
- if (map != null) {
- GLES20Canvas.initAtlas(buffer, map);
- }
- // If IAssetAtlas is not the same class as the IBinder
- // we are using a remote service and we can safely
- // destroy the graphic buffer
- if (atlas.getClass() != binder.getClass()) {
- buffer.destroy();
- }
- }
- }
- } catch (RemoteException e) {
- Log.w(LOG_TAG, "Could not acquire atlas", e);
- }
- }
-
- boolean canDraw() {
- return mGl != null && mCanvas != null && mGlCanvas != null;
- }
-
- int onPreDraw(Rect dirty) {
- return mGlCanvas.onPreDraw(dirty);
- }
-
- void onPostDraw() {
- mGlCanvas.onPostDraw();
- }
-
- void drawProfileData(View.AttachInfo attachInfo) {
- if (mDebugDataProvider != null) {
- final GraphDataProvider provider = mDebugDataProvider;
- initProfileDrawData(attachInfo, provider);
-
- final int height = provider.getVerticalUnitSize();
- final int margin = provider.getHorizontaUnitMargin();
- final int width = provider.getHorizontalUnitSize();
-
- int x = 0;
- int count = 0;
- int current = 0;
-
- final float[] data = provider.getData();
- final int elementCount = provider.getElementCount();
- final int graphType = provider.getGraphType();
-
- int totalCount = provider.getFrameCount() * elementCount;
- if (graphType == GraphDataProvider.GRAPH_TYPE_LINES) {
- totalCount -= elementCount;
- }
-
- for (int i = 0; i < totalCount; i += elementCount) {
- if (data[i] < 0.0f) break;
-
- int index = count * 4;
- if (i == provider.getCurrentFrame() * elementCount) current = index;
-
- x += margin;
- int x2 = x + width;
-
- int y2 = mHeight;
- int y1 = (int) (y2 - data[i] * height);
-
- switch (graphType) {
- case GraphDataProvider.GRAPH_TYPE_BARS: {
- for (int j = 0; j < elementCount; j++) {
- //noinspection MismatchedReadAndWriteOfArray
- final float[] r = mProfileShapes[j];
- r[index] = x;
- r[index + 1] = y1;
- r[index + 2] = x2;
- r[index + 3] = y2;
-
- y2 = y1;
- if (j < elementCount - 1) {
- y1 = (int) (y2 - data[i + j + 1] * height);
- }
- }
- } break;
- case GraphDataProvider.GRAPH_TYPE_LINES: {
- for (int j = 0; j < elementCount; j++) {
- //noinspection MismatchedReadAndWriteOfArray
- final float[] r = mProfileShapes[j];
- r[index] = (x + x2) * 0.5f;
- r[index + 1] = index == 0 ? y1 : r[index - 1];
- r[index + 2] = r[index] + width;
- r[index + 3] = y1;
-
- y2 = y1;
- if (j < elementCount - 1) {
- y1 = (int) (y2 - data[i + j + 1] * height);
- }
- }
- } break;
- }
-
-
- x += width;
- count++;
- }
-
- x += margin;
-
- drawGraph(graphType, count);
- drawCurrentFrame(graphType, current);
- drawThreshold(x, height);
- }
- }
-
- private void drawGraph(int graphType, int count) {
- for (int i = 0; i < mProfileShapes.length; i++) {
- mDebugDataProvider.setupGraphPaint(mProfilePaint, i);
- switch (graphType) {
- case GraphDataProvider.GRAPH_TYPE_BARS:
- mGlCanvas.drawRects(mProfileShapes[i], count * 4, mProfilePaint);
- break;
- case GraphDataProvider.GRAPH_TYPE_LINES:
- mGlCanvas.drawLines(mProfileShapes[i], 0, count * 4, mProfilePaint);
- break;
- }
- }
- }
-
- private void drawCurrentFrame(int graphType, int index) {
- if (index >= 0) {
- mDebugDataProvider.setupCurrentFramePaint(mProfilePaint);
- switch (graphType) {
- case GraphDataProvider.GRAPH_TYPE_BARS:
- mGlCanvas.drawRect(mProfileShapes[2][index], mProfileShapes[2][index + 1],
- mProfileShapes[2][index + 2], mProfileShapes[0][index + 3],
- mProfilePaint);
- break;
- case GraphDataProvider.GRAPH_TYPE_LINES:
- mGlCanvas.drawLine(mProfileShapes[2][index], mProfileShapes[2][index + 1],
- mProfileShapes[2][index], mHeight, mProfilePaint);
- break;
- }
- }
- }
-
- private void drawThreshold(int x, int height) {
- float threshold = mDebugDataProvider.getThreshold();
- if (threshold > 0.0f) {
- mDebugDataProvider.setupThresholdPaint(mProfilePaint);
- int y = (int) (mHeight - threshold * height);
- mGlCanvas.drawLine(0.0f, y, x, y, mProfilePaint);
- }
- }
-
- private void initProfileDrawData(View.AttachInfo attachInfo, GraphDataProvider provider) {
- if (mProfileShapes == null) {
- final int elementCount = provider.getElementCount();
- final int frameCount = provider.getFrameCount();
-
- mProfileShapes = new float[elementCount][];
- for (int i = 0; i < elementCount; i++) {
- mProfileShapes[i] = new float[frameCount * 4];
- }
-
- mProfilePaint = new Paint();
- }
-
- mProfilePaint.reset();
- if (provider.getGraphType() == GraphDataProvider.GRAPH_TYPE_LINES) {
- mProfilePaint.setAntiAlias(true);
- }
-
- if (mDisplayMetrics == null) {
- mDisplayMetrics = new DisplayMetrics();
- }
-
- attachInfo.mDisplay.getMetrics(mDisplayMetrics);
- provider.prepare(mDisplayMetrics);
- }
-
- @Override
- void destroy(boolean full) {
- try {
- if (full && mCanvas != null) {
- mCanvas = null;
- }
-
- if (!isEnabled() || mDestroyed) {
- setEnabled(false);
- return;
- }
-
- destroySurface();
- setEnabled(false);
-
- mDestroyed = true;
- mGl = null;
- } finally {
- if (full && mGlCanvas != null) {
- mGlCanvas = null;
- }
- }
- }
-
- @Override
- void pushLayerUpdate(HardwareLayer layer) {
- mLayerUpdates.add(layer);
- }
-
- @Override
- void flushLayerUpdates() {
- if (validate()) {
- flushLayerChanges();
- mGlCanvas.flushLayerUpdates();
- }
- }
-
- @Override
- HardwareLayer createTextureLayer() {
- validate();
- return HardwareLayer.createTextureLayer(this);
- }
-
- @Override
- public HardwareLayer createDisplayListLayer(int width, int height) {
- validate();
- return HardwareLayer.createDisplayListLayer(this, width, height);
- }
-
- boolean hasContext() {
- return sEgl != null && mEglContext != null
- && mEglContext.equals(sEgl.eglGetCurrentContext());
- }
-
- @Override
- void onLayerDestroyed(HardwareLayer layer) {
- if (mGlCanvas != null) {
- mGlCanvas.cancelLayerUpdate(layer);
- }
- mLayerUpdates.remove(layer);
- }
-
- @Override
- public SurfaceTexture createSurfaceTexture(HardwareLayer layer) {
- return layer.createSurfaceTexture();
- }
-
- @Override
- boolean copyLayerInto(HardwareLayer layer, Bitmap bitmap) {
- if (!validate()) {
- throw new IllegalStateException("Could not acquire hardware rendering context");
- }
- layer.flushChanges();
- return GLES20Canvas.nCopyLayer(layer.getLayer(), bitmap.mNativeBitmap);
- }
-
- @Override
- boolean safelyRun(Runnable action) {
- boolean needsContext = !isEnabled() || checkRenderContext() == SURFACE_STATE_ERROR;
-
- if (needsContext) {
- GLRendererEglContext managedContext =
- (GLRendererEglContext) sEglContextStorage.get();
- if (managedContext == null) return false;
- usePbufferSurface(managedContext.getContext());
- }
-
- try {
- action.run();
- } finally {
- if (needsContext) {
- sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE,
- EGL_NO_SURFACE, EGL_NO_CONTEXT);
- }
- }
-
- return true;
- }
-
- @Override
- void invokeFunctor(long functor, boolean waitForCompletion) {
- boolean needsContext = !isEnabled() || checkRenderContext() == SURFACE_STATE_ERROR;
- boolean hasContext = !needsContext;
-
- if (needsContext) {
- GLRendererEglContext managedContext =
- (GLRendererEglContext) sEglContextStorage.get();
- if (managedContext != null) {
- usePbufferSurface(managedContext.getContext());
- hasContext = true;
- }
- }
-
- try {
- nInvokeFunctor(functor, hasContext);
- } finally {
- if (needsContext) {
- sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE,
- EGL_NO_SURFACE, EGL_NO_CONTEXT);
- }
- }
- }
-
- private static native void nInvokeFunctor(long functor, boolean hasContext);
-
- @Override
- void destroyHardwareResources(final View view) {
- if (view != null) {
- safelyRun(new Runnable() {
- @Override
- public void run() {
- if (mCanvas != null) {
- mCanvas.clearLayerUpdates();
- }
- destroyResources(view);
- GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_LAYERS);
- }
- });
- }
- }
-
- private static void destroyResources(View view) {
- view.destroyHardwareResources();
-
- if (view instanceof ViewGroup) {
- ViewGroup group = (ViewGroup) view;
-
- int count = group.getChildCount();
- for (int i = 0; i < count; i++) {
- destroyResources(group.getChildAt(i));
- }
- }
- }
-
- static void startTrimMemory(int level) {
- if (sEgl == null || sEglConfig == null) return;
-
- GLRendererEglContext managedContext =
- (GLRendererEglContext) sEglContextStorage.get();
- // We do not have OpenGL objects
- if (managedContext == null) {
- return;
- } else {
- usePbufferSurface(managedContext.getContext());
- }
-
- if (level >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
- GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_FULL);
- } else if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
- GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_MODERATE);
- }
- }
-
- static void endTrimMemory() {
- if (sEgl != null && sEglDisplay != null) {
- sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- }
- }
-
- private static void usePbufferSurface(EGLContext eglContext) {
- synchronized (sPbufferLock) {
- // Create a temporary 1x1 pbuffer so we have a context
- // to clear our OpenGL objects
- if (sPbuffer == null) {
- sPbuffer = sEgl.eglCreatePbufferSurface(sEglDisplay, sEglConfig, new int[] {
- EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE
- });
- }
- }
- sEgl.eglMakeCurrent(sEglDisplay, sPbuffer, sPbuffer, eglContext);
- }
-
- GLRenderer(boolean translucent) {
- mTranslucent = translucent;
-
- loadSystemProperties();
- }
-
- @Override
- void setOpaque(boolean opaque) {
- // Not supported
- }
-
- @Override
- boolean loadSystemProperties() {
- boolean value;
- boolean changed = false;
-
- String profiling = SystemProperties.get(PROFILE_PROPERTY);
- int graphType = search(VISUALIZERS, profiling);
- value = graphType >= 0;
-
- if (graphType != mProfileVisualizerType) {
- changed = true;
- mProfileVisualizerType = graphType;
-
- mProfileShapes = null;
- mProfilePaint = null;
-
- if (value) {
- mDebugDataProvider = new GraphDataProvider(graphType);
- } else {
- mDebugDataProvider = null;
- }
- }
-
- // If on-screen profiling is not enabled, we need to check whether
- // console profiling only is enabled
- if (!value) {
- value = Boolean.parseBoolean(profiling);
- }
-
- if (value != mProfileEnabled) {
- changed = true;
- mProfileEnabled = value;
-
- if (mProfileEnabled) {
- Log.d(LOG_TAG, "Profiling hardware renderer");
-
- int maxProfileFrames = SystemProperties.getInt(PROFILE_MAXFRAMES_PROPERTY,
- PROFILE_MAX_FRAMES);
- mProfileData = new float[maxProfileFrames * PROFILE_FRAME_DATA_COUNT];
- for (int i = 0; i < mProfileData.length; i += PROFILE_FRAME_DATA_COUNT) {
- mProfileData[i] = mProfileData[i + 1] = mProfileData[i + 2] = -1;
- }
-
- mProfileLock = new ReentrantLock();
- } else {
- mProfileData = null;
- mProfileLock = null;
- mProfileVisualizerType = -1;
- }
-
- mProfileCurrentFrame = -PROFILE_FRAME_DATA_COUNT;
- }
-
- value = SystemProperties.getBoolean(DEBUG_DIRTY_REGIONS_PROPERTY, false);
- if (value != mDebugDirtyRegions) {
- changed = true;
- mDebugDirtyRegions = value;
-
- if (mDebugDirtyRegions) {
- Log.d(LOG_TAG, "Debugging dirty regions");
- }
- }
-
- String overdraw = SystemProperties.get(HardwareRenderer.DEBUG_OVERDRAW_PROPERTY);
- int debugOverdraw = search(OVERDRAW, overdraw);
- if (debugOverdraw != mDebugOverdraw) {
- changed = true;
- mDebugOverdraw = debugOverdraw;
- }
-
- if (loadProperties()) {
- changed = true;
- }
-
- return changed;
- }
-
- private static int search(String[] values, String value) {
- for (int i = 0; i < values.length; i++) {
- if (values[i].equals(value)) return i;
- }
- return -1;
- }
-
- @Override
- void dumpGfxInfo(PrintWriter pw, FileDescriptor fd) {
- if (mProfileEnabled) {
- pw.printf("\n\tDraw\tProcess\tExecute\n");
-
- mProfileLock.lock();
- try {
- for (int i = 0; i < mProfileData.length; i += PROFILE_FRAME_DATA_COUNT) {
- if (mProfileData[i] < 0) {
- break;
- }
- pw.printf("\t%3.2f\t%3.2f\t%3.2f\n", mProfileData[i], mProfileData[i + 1],
- mProfileData[i + 2]);
- mProfileData[i] = mProfileData[i + 1] = mProfileData[i + 2] = -1;
- }
- mProfileCurrentFrame = mProfileData.length;
- } finally {
- mProfileLock.unlock();
- }
- }
- }
-
- /**
- * Indicates whether this renderer instance can track and update dirty regions.
- */
- boolean hasDirtyRegions() {
- return mDirtyRegionsEnabled;
- }
-
- /**
- * Checks for OpenGL errors. If an error has occured, {@link #destroy(boolean)}
- * is invoked and the requested flag is turned off. The error code is
- * also logged as a warning.
- */
- void checkEglErrors() {
- if (isEnabled()) {
- checkEglErrorsForced();
- }
- }
-
- private void checkEglErrorsForced() {
- int error = sEgl.eglGetError();
- if (error != EGL_SUCCESS) {
- // something bad has happened revert to
- // normal rendering.
- Log.w(LOG_TAG, "EGL error: " + GLUtils.getEGLErrorString(error));
- fallback(error != EGL11.EGL_CONTEXT_LOST);
- }
- }
-
- private void fallback(boolean fallback) {
- destroy(true);
- if (fallback) {
- // we'll try again if it was context lost
- setRequested(false);
- Log.w(LOG_TAG, "Mountain View, we've had a problem here. "
- + "Switching back to software rendering.");
- }
- }
-
- @Override
- boolean initialize(Surface surface) throws OutOfResourcesException {
- if (isRequested() && !isEnabled()) {
- boolean contextCreated = initializeEgl();
- mGl = createEglSurface(surface);
- mDestroyed = false;
-
- if (mGl != null) {
- int err = sEgl.eglGetError();
- if (err != EGL_SUCCESS) {
- destroy(true);
- setRequested(false);
- } else {
- if (mCanvas == null) {
- mCanvas = createCanvas();
- }
- setEnabled(true);
-
- if (contextCreated) {
- initAtlas();
- }
- }
-
- return mCanvas != null;
- }
- }
- return false;
- }
-
- @Override
- void updateSurface(Surface surface) throws OutOfResourcesException {
- if (isRequested() && isEnabled()) {
- createEglSurface(surface);
- }
- }
-
- @Override
- void pauseSurface(Surface surface) {
- // No-op
- }
-
- boolean initializeEgl() {
- synchronized (sEglLock) {
- if (sEgl == null && sEglConfig == null) {
- sEgl = (EGL10) EGLContext.getEGL();
-
- // Get to the default display.
- sEglDisplay = sEgl.eglGetDisplay(EGL_DEFAULT_DISPLAY);
-
- if (sEglDisplay == EGL_NO_DISPLAY) {
- throw new RuntimeException("eglGetDisplay failed "
- + GLUtils.getEGLErrorString(sEgl.eglGetError()));
- }
-
- // We can now initialize EGL for that display
- int[] version = new int[2];
- if (!sEgl.eglInitialize(sEglDisplay, version)) {
- throw new RuntimeException("eglInitialize failed " +
- GLUtils.getEGLErrorString(sEgl.eglGetError()));
- }
-
- checkEglErrorsForced();
-
- sEglConfig = loadEglConfig();
- }
- }
-
- ManagedEGLContext managedContext = sEglContextStorage.get();
- mEglContext = managedContext != null ? managedContext.getContext() : null;
- mEglThread = Thread.currentThread();
-
- if (mEglContext == null) {
- mEglContext = createContext(sEgl, sEglDisplay, sEglConfig);
- sEglContextStorage.set(createManagedContext(mEglContext));
- return true;
- }
-
- return false;
- }
-
- private EGLConfig loadEglConfig() {
- EGLConfig eglConfig = chooseEglConfig();
- if (eglConfig == null) {
- // We tried to use EGL_SWAP_BEHAVIOR_PRESERVED_BIT, try again without
- if (sDirtyRegions) {
- sDirtyRegions = false;
- eglConfig = chooseEglConfig();
- if (eglConfig == null) {
- throw new RuntimeException("eglConfig not initialized");
- }
- } else {
- throw new RuntimeException("eglConfig not initialized");
- }
- }
- return eglConfig;
- }
-
- private EGLConfig chooseEglConfig() {
- EGLConfig[] configs = new EGLConfig[1];
- int[] configsCount = new int[1];
- int[] configSpec = getConfig(sDirtyRegions);
-
- // Debug
- final String debug = SystemProperties.get(PRINT_CONFIG_PROPERTY, "");
- if ("all".equalsIgnoreCase(debug)) {
- sEgl.eglChooseConfig(sEglDisplay, configSpec, null, 0, configsCount);
-
- EGLConfig[] debugConfigs = new EGLConfig[configsCount[0]];
- sEgl.eglChooseConfig(sEglDisplay, configSpec, debugConfigs,
- configsCount[0], configsCount);
-
- for (EGLConfig config : debugConfigs) {
- printConfig(config);
- }
- }
-
- if (!sEgl.eglChooseConfig(sEglDisplay, configSpec, configs, 1, configsCount)) {
- throw new IllegalArgumentException("eglChooseConfig failed " +
- GLUtils.getEGLErrorString(sEgl.eglGetError()));
- } else if (configsCount[0] > 0) {
- if ("choice".equalsIgnoreCase(debug)) {
- printConfig(configs[0]);
- }
- return configs[0];
- }
-
- return null;
- }
-
- private static void printConfig(EGLConfig config) {
- int[] value = new int[1];
-
- Log.d(LOG_TAG, "EGL configuration " + config + ":");
-
- sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_RED_SIZE, value);
- Log.d(LOG_TAG, " RED_SIZE = " + value[0]);
-
- sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_GREEN_SIZE, value);
- Log.d(LOG_TAG, " GREEN_SIZE = " + value[0]);
-
- sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_BLUE_SIZE, value);
- Log.d(LOG_TAG, " BLUE_SIZE = " + value[0]);
-
- sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_ALPHA_SIZE, value);
- Log.d(LOG_TAG, " ALPHA_SIZE = " + value[0]);
-
- sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_DEPTH_SIZE, value);
- Log.d(LOG_TAG, " DEPTH_SIZE = " + value[0]);
-
- sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_STENCIL_SIZE, value);
- Log.d(LOG_TAG, " STENCIL_SIZE = " + value[0]);
-
- sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_SAMPLE_BUFFERS, value);
- Log.d(LOG_TAG, " SAMPLE_BUFFERS = " + value[0]);
-
- sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_SAMPLES, value);
- Log.d(LOG_TAG, " SAMPLES = " + value[0]);
-
- sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_SURFACE_TYPE, value);
- Log.d(LOG_TAG, " SURFACE_TYPE = 0x" + Integer.toHexString(value[0]));
-
- sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_CONFIG_CAVEAT, value);
- Log.d(LOG_TAG, " CONFIG_CAVEAT = 0x" + Integer.toHexString(value[0]));
- }
-
- GL createEglSurface(Surface surface) throws OutOfResourcesException {
- // Check preconditions.
- if (sEgl == null) {
- throw new RuntimeException("egl not initialized");
- }
- if (sEglDisplay == null) {
- throw new RuntimeException("eglDisplay not initialized");
- }
- if (sEglConfig == null) {
- throw new RuntimeException("eglConfig not initialized");
- }
- if (Thread.currentThread() != mEglThread) {
- throw new IllegalStateException("HardwareRenderer cannot be used "
- + "from multiple threads");
- }
-
- // In case we need to destroy an existing surface
- destroySurface();
-
- // Create an EGL surface we can render into.
- if (!createSurface(surface)) {
- return null;
- }
-
- initCaches();
-
- return mEglContext.getGL();
- }
-
- private void enableDirtyRegions() {
- // If mDirtyRegions is set, this means we have an EGL configuration
- // with EGL_SWAP_BEHAVIOR_PRESERVED_BIT set
- if (sDirtyRegions) {
- if (!(mDirtyRegionsEnabled = preserveBackBuffer())) {
- Log.w(LOG_TAG, "Backbuffer cannot be preserved");
- }
- } else if (sDirtyRegionsRequested) {
- // If mDirtyRegions is not set, our EGL configuration does not
- // have EGL_SWAP_BEHAVIOR_PRESERVED_BIT; however, the default
- // swap behavior might be EGL_BUFFER_PRESERVED, which means we
- // want to set mDirtyRegions. We try to do this only if dirty
- // regions were initially requested as part of the device
- // configuration (see RENDER_DIRTY_REGIONS)
- mDirtyRegionsEnabled = isBackBufferPreserved();
- }
- }
-
- EGLContext createContext(EGL10 egl, EGLDisplay eglDisplay, EGLConfig eglConfig) {
- final int[] attribs = { EGL14.EGL_CONTEXT_CLIENT_VERSION, GL_VERSION, EGL_NONE };
-
- EGLContext context = egl.eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT,
- attribs);
- if (context == null || context == EGL_NO_CONTEXT) {
- //noinspection ConstantConditions
- throw new IllegalStateException(
- "Could not create an EGL context. eglCreateContext failed with error: " +
- GLUtils.getEGLErrorString(sEgl.eglGetError()));
- }
-
- return context;
- }
-
- void destroySurface() {
- if (mEglSurface != null && mEglSurface != EGL_NO_SURFACE) {
- if (mEglSurface.equals(sEgl.eglGetCurrentSurface(EGL_DRAW))) {
- sEgl.eglMakeCurrent(sEglDisplay,
- EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- }
- sEgl.eglDestroySurface(sEglDisplay, mEglSurface);
- mEglSurface = null;
- }
- }
-
- @Override
- void invalidate(Surface surface) {
- // Cancels any existing buffer to ensure we'll get a buffer
- // of the right size before we call eglSwapBuffers
- sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-
- if (mEglSurface != null && mEglSurface != EGL_NO_SURFACE) {
- sEgl.eglDestroySurface(sEglDisplay, mEglSurface);
- mEglSurface = null;
- setEnabled(false);
- }
-
- if (surface.isValid()) {
- if (!createSurface(surface)) {
- return;
- }
-
- mUpdateDirtyRegions = true;
-
- if (mCanvas != null) {
- setEnabled(true);
- }
- }
- }
-
- private boolean createSurface(Surface surface) {
- mEglSurface = sEgl.eglCreateWindowSurface(sEglDisplay, sEglConfig, surface, null);
-
- if (mEglSurface == null || mEglSurface == EGL_NO_SURFACE) {
- int error = sEgl.eglGetError();
- if (error == EGL_BAD_NATIVE_WINDOW) {
- Log.e(LOG_TAG, "createWindowSurface returned EGL_BAD_NATIVE_WINDOW.");
- return false;
- }
- throw new RuntimeException("createWindowSurface failed "
- + GLUtils.getEGLErrorString(error));
- }
-
- if (!sEgl.eglMakeCurrent(sEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
- throw new IllegalStateException("eglMakeCurrent failed " +
- GLUtils.getEGLErrorString(sEgl.eglGetError()));
- }
-
- enableDirtyRegions();
-
- return true;
- }
-
- boolean validate() {
- return checkRenderContext() != SURFACE_STATE_ERROR;
- }
-
- @Override
- void setup(int width, int height, float lightX, float lightY, float lightZ, float lightRadius) {
- if (validate()) {
- mCanvas.setViewport(width, height);
- mCanvas.initializeLight(lightX, lightY, lightZ, lightRadius);
- mWidth = width;
- mHeight = height;
- }
- }
-
- @Override
- int getWidth() {
- return mWidth;
- }
-
- @Override
- int getHeight() {
- return mHeight;
- }
-
- @Override
- void setName(String name) {
- mName = name;
- }
-
- @Override
- void draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks,
- Rect dirty) {
- if (canDraw()) {
- if (!hasDirtyRegions()) {
- dirty = null;
- }
- attachInfo.mIgnoreDirtyState = true;
- attachInfo.mDrawingTime = SystemClock.uptimeMillis();
-
- view.mPrivateFlags |= View.PFLAG_DRAWN;
-
- // We are already on the correct thread
- final int surfaceState = checkRenderContextUnsafe();
- if (surfaceState != SURFACE_STATE_ERROR) {
- HardwareCanvas canvas = mCanvas;
-
- if (mProfileEnabled) {
- mProfileLock.lock();
- }
-
- dirty = beginFrame(canvas, dirty, surfaceState);
-
- RenderNode displayList = buildDisplayList(view, canvas);
-
- flushLayerChanges();
-
- // buildDisplayList() calls into user code which can cause
- // an eglMakeCurrent to happen with a different surface/context.
- // We must therefore check again here.
- if (checkRenderContextUnsafe() == SURFACE_STATE_ERROR) {
- return;
- }
-
- int saveCount = 0;
- int status = RenderNode.STATUS_DONE;
-
- long start = getSystemTime();
- try {
- status = prepareFrame(dirty);
-
- saveCount = canvas.save();
- callbacks.onHardwarePreDraw(canvas);
-
- if (displayList != null) {
- status |= drawDisplayList(canvas, displayList, status);
- } else {
- // Shouldn't reach here
- view.draw(canvas);
- }
- } catch (Exception e) {
- Log.e(LOG_TAG, "An error has occurred while drawing:", e);
- } finally {
- callbacks.onHardwarePostDraw(canvas);
- canvas.restoreToCount(saveCount);
- view.mRecreateDisplayList = false;
-
- mDrawDelta = getSystemTime() - start;
-
- if (mDrawDelta > 0) {
- mFrameCount++;
-
- debugDirtyRegions(dirty, canvas);
- drawProfileData(attachInfo);
- }
- }
-
- onPostDraw();
-
- swapBuffers(status);
-
- if (mProfileEnabled) {
- mProfileLock.unlock();
- }
-
- attachInfo.mIgnoreDirtyState = false;
- }
- }
- }
-
- private void flushLayerChanges() {
- // Loop through and apply any pending layer changes
- for (int i = 0; i < mLayerUpdates.size(); i++) {
- HardwareLayer layer = mLayerUpdates.get(i);
- layer.flushChanges();
- if (!layer.isValid()) {
- // The layer was removed from mAttachedLayers, rewind i by 1
- // Note that this shouldn't actually happen as View.getHardwareLayer()
- // is already flushing for error checking reasons
- i--;
- } else if (layer.hasDisplayList()) {
- mCanvas.pushLayerUpdate(layer);
- }
- }
- mLayerUpdates.clear();
- }
-
- @Override
- void fence() {
- // Everything is immediate, so this is a no-op
- }
-
- private RenderNode buildDisplayList(View view, HardwareCanvas canvas) {
- view.mRecreateDisplayList = (view.mPrivateFlags & View.PFLAG_INVALIDATED)
- == View.PFLAG_INVALIDATED;
- view.mPrivateFlags &= ~View.PFLAG_INVALIDATED;
-
- long buildDisplayListStartTime = startBuildDisplayListProfiling();
- canvas.clearLayerUpdates();
-
- Trace.traceBegin(Trace.TRACE_TAG_VIEW, "getDisplayList");
- RenderNode renderNode = view.getDisplayList();
- Trace.traceEnd(Trace.TRACE_TAG_VIEW);
-
- endBuildDisplayListProfiling(buildDisplayListStartTime);
-
- return renderNode;
- }
-
- private Rect beginFrame(HardwareCanvas canvas, Rect dirty, int surfaceState) {
- // We had to change the current surface and/or context, redraw everything
- if (surfaceState == SURFACE_STATE_UPDATED) {
- dirty = null;
- beginFrame(null);
- } else {
- int[] size = mSurfaceSize;
- beginFrame(size);
-
- if (size[1] != mHeight || size[0] != mWidth) {
- mWidth = size[0];
- mHeight = size[1];
-
- canvas.setViewport(mWidth, mHeight);
-
- dirty = null;
- }
- }
-
- if (mDebugDataProvider != null) dirty = null;
-
- return dirty;
- }
-
- private long startBuildDisplayListProfiling() {
- if (mProfileEnabled) {
- mProfileCurrentFrame += PROFILE_FRAME_DATA_COUNT;
- if (mProfileCurrentFrame >= mProfileData.length) {
- mProfileCurrentFrame = 0;
- }
-
- return System.nanoTime();
- }
- return 0;
- }
-
- private void endBuildDisplayListProfiling(long getDisplayListStartTime) {
- if (mProfileEnabled) {
- long now = System.nanoTime();
- float total = (now - getDisplayListStartTime) * 0.000001f;
- //noinspection PointlessArithmeticExpression
- mProfileData[mProfileCurrentFrame] = total;
- }
- }
-
- private int prepareFrame(Rect dirty) {
- int status;
- Trace.traceBegin(Trace.TRACE_TAG_VIEW, "prepareFrame");
- try {
- status = onPreDraw(dirty);
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_VIEW);
- }
- return status;
- }
-
- private int drawDisplayList(HardwareCanvas canvas, RenderNode displayList,
- int status) {
-
- long drawDisplayListStartTime = 0;
- if (mProfileEnabled) {
- drawDisplayListStartTime = System.nanoTime();
- }
-
- Trace.traceBegin(Trace.TRACE_TAG_VIEW, "drawDisplayList");
- nPrepareTree(displayList.getNativeDisplayList());
- try {
- status |= canvas.drawDisplayList(displayList, mRedrawClip,
- RenderNode.FLAG_CLIP_CHILDREN);
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_VIEW);
- }
-
- if (mProfileEnabled) {
- long now = System.nanoTime();
- float total = (now - drawDisplayListStartTime) * 0.000001f;
- mProfileData[mProfileCurrentFrame + 1] = total;
- }
-
- return status;
- }
-
- private void swapBuffers(int status) {
- if ((status & RenderNode.STATUS_DREW) == RenderNode.STATUS_DREW) {
- long eglSwapBuffersStartTime = 0;
- if (mProfileEnabled) {
- eglSwapBuffersStartTime = System.nanoTime();
- }
-
- sEgl.eglSwapBuffers(sEglDisplay, mEglSurface);
-
- if (mProfileEnabled) {
- long now = System.nanoTime();
- float total = (now - eglSwapBuffersStartTime) * 0.000001f;
- mProfileData[mProfileCurrentFrame + 2] = total;
- }
-
- checkEglErrors();
- }
- }
-
- private void debugDirtyRegions(Rect dirty, HardwareCanvas canvas) {
- if (mDebugDirtyRegions) {
- if (mDebugPaint == null) {
- mDebugPaint = new Paint();
- mDebugPaint.setColor(0x7fff0000);
- }
-
- if (dirty != null && (mFrameCount & 1) == 0) {
- canvas.drawRect(dirty, mDebugPaint);
- }
- }
- }
-
- /**
- * Ensures the current EGL context and surface are the ones we expect.
- * This method throws an IllegalStateException if invoked from a thread
- * that did not initialize EGL.
- *
- * @return {@link #SURFACE_STATE_ERROR} if the correct EGL context cannot be made current,
- * {@link #SURFACE_STATE_UPDATED} if the EGL context was changed or
- * {@link #SURFACE_STATE_SUCCESS} if the EGL context was the correct one
- *
- * @see #checkRenderContextUnsafe()
- */
- int checkRenderContext() {
- if (mEglThread != Thread.currentThread()) {
- throw new IllegalStateException("Hardware acceleration can only be used with a " +
- "single UI thread.\nOriginal thread: " + mEglThread + "\n" +
- "Current thread: " + Thread.currentThread());
- }
-
- return checkRenderContextUnsafe();
- }
-
- /**
- * Ensures the current EGL context and surface are the ones we expect.
- * This method does not check the current thread.
- *
- * @return {@link #SURFACE_STATE_ERROR} if the correct EGL context cannot be made current,
- * {@link #SURFACE_STATE_UPDATED} if the EGL context was changed or
- * {@link #SURFACE_STATE_SUCCESS} if the EGL context was the correct one
- *
- * @see #checkRenderContext()
- */
- private int checkRenderContextUnsafe() {
- if (!mEglSurface.equals(sEgl.eglGetCurrentSurface(EGL_DRAW)) ||
- !mEglContext.equals(sEgl.eglGetCurrentContext())) {
- if (!sEgl.eglMakeCurrent(sEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
- Log.e(LOG_TAG, "eglMakeCurrent failed " +
- GLUtils.getEGLErrorString(sEgl.eglGetError()));
- fallback(true);
- return SURFACE_STATE_ERROR;
- } else {
- if (mUpdateDirtyRegions) {
- enableDirtyRegions();
- mUpdateDirtyRegions = false;
- }
- return SURFACE_STATE_UPDATED;
- }
- }
- return SURFACE_STATE_SUCCESS;
- }
-
- private static int dpToPx(int dp, float density) {
- return (int) (dp * density + 0.5f);
- }
-
- static native boolean loadProperties();
-
- static native void setupShadersDiskCache(String cacheFile);
-
- /**
- * Notifies EGL that the frame is about to be rendered.
- * @param size
- */
- static native void beginFrame(int[] size);
-
- /**
- * Returns the current system time according to the renderer.
- * This method is used for debugging only and should not be used
- * as a clock.
- */
- static native long getSystemTime();
-
- /**
- * Preserves the back buffer of the current surface after a buffer swap.
- * Calling this method sets the EGL_SWAP_BEHAVIOR attribute of the current
- * surface to EGL_BUFFER_PRESERVED. Calling this method requires an EGL
- * config that supports EGL_SWAP_BEHAVIOR_PRESERVED_BIT.
- *
- * @return True if the swap behavior was successfully changed,
- * false otherwise.
- */
- static native boolean preserveBackBuffer();
-
- /**
- * Indicates whether the current surface preserves its back buffer
- * after a buffer swap.
- *
- * @return True, if the surface's EGL_SWAP_BEHAVIOR is EGL_BUFFER_PRESERVED,
- * false otherwise
- */
- static native boolean isBackBufferPreserved();
-
- static native void nDestroyLayer(long layerPtr);
-
- private static native void nPrepareTree(long displayListPtr);
-
- class GraphDataProvider {
- /**
- * Draws the graph as bars. Frame elements are stacked on top of
- * each other.
- */
- public static final int GRAPH_TYPE_BARS = 0;
- /**
- * Draws the graph as lines. The number of series drawn corresponds
- * to the number of elements.
- */
- public static final int GRAPH_TYPE_LINES = 1;
-
- private final int mGraphType;
-
- private int mVerticalUnit;
- private int mHorizontalUnit;
- private int mHorizontalMargin;
- private int mThresholdStroke;
-
- public GraphDataProvider(int graphType) {
- mGraphType = graphType;
- }
-
- void prepare(DisplayMetrics metrics) {
- final float density = metrics.density;
-
- mVerticalUnit = dpToPx(PROFILE_DRAW_DP_PER_MS, density);
- mHorizontalUnit = dpToPx(PROFILE_DRAW_WIDTH, density);
- mHorizontalMargin = dpToPx(PROFILE_DRAW_MARGIN, density);
- mThresholdStroke = dpToPx(PROFILE_DRAW_THRESHOLD_STROKE_WIDTH, density);
- }
-
- int getGraphType() {
- return mGraphType;
- }
-
- int getVerticalUnitSize() {
- return mVerticalUnit;
- }
-
- int getHorizontalUnitSize() {
- return mHorizontalUnit;
- }
-
- int getHorizontaUnitMargin() {
- return mHorizontalMargin;
- }
-
- float[] getData() {
- return mProfileData;
- }
-
- float getThreshold() {
- return 16;
- }
-
- int getFrameCount() {
- return mProfileData.length / PROFILE_FRAME_DATA_COUNT;
- }
-
- int getElementCount() {
- return PROFILE_FRAME_DATA_COUNT;
- }
-
- int getCurrentFrame() {
- return mProfileCurrentFrame / PROFILE_FRAME_DATA_COUNT;
- }
-
- void setupGraphPaint(Paint paint, int elementIndex) {
- paint.setColor(PROFILE_DRAW_COLORS[elementIndex]);
- if (mGraphType == GRAPH_TYPE_LINES) paint.setStrokeWidth(mThresholdStroke);
- }
-
- void setupThresholdPaint(Paint paint) {
- paint.setColor(PROFILE_DRAW_THRESHOLD_COLOR);
- paint.setStrokeWidth(mThresholdStroke);
- }
-
- void setupCurrentFramePaint(Paint paint) {
- paint.setColor(PROFILE_DRAW_CURRENT_FRAME_COLOR);
- if (mGraphType == GRAPH_TYPE_LINES) paint.setStrokeWidth(mThresholdStroke);
- }
- }
-}
diff --git a/core/java/android/view/HardwareCanvas.java b/core/java/android/view/HardwareCanvas.java
index 9568760..b8e7d8c 100644
--- a/core/java/android/view/HardwareCanvas.java
+++ b/core/java/android/view/HardwareCanvas.java
@@ -110,48 +110,6 @@
return RenderNode.STATUS_DONE;
}
- /**
- * Indicates that the specified layer must be updated as soon as possible.
- *
- * @param layer The layer to update
- *
- * @see #clearLayerUpdates()
- *
- * @hide
- */
- abstract void pushLayerUpdate(HardwareLayer layer);
-
- /**
- * Cancels a queued layer update. If the specified layer was not
- * queued for update, this method has no effect.
- *
- * @param layer The layer whose update to cancel
- *
- * @see #pushLayerUpdate(HardwareLayer)
- * @see #clearLayerUpdates()
- *
- * @hide
- */
- abstract void cancelLayerUpdate(HardwareLayer layer);
-
- /**
- * Immediately executes all enqueued layer updates.
- *
- * @see #pushLayerUpdate(HardwareLayer)
- *
- * @hide
- */
- abstract void flushLayerUpdates();
-
- /**
- * Removes all enqueued layer updates.
- *
- * @see #pushLayerUpdate(HardwareLayer)
- *
- * @hide
- */
- abstract void clearLayerUpdates();
-
public abstract void drawCircle(CanvasProperty<Float> cx, CanvasProperty<Float> cy,
CanvasProperty<Float> radius, CanvasProperty<Paint> paint);
}
diff --git a/core/java/android/view/HardwareLayer.java b/core/java/android/view/HardwareLayer.java
index 652bcd2..6acb134 100644
--- a/core/java/android/view/HardwareLayer.java
+++ b/core/java/android/view/HardwareLayer.java
@@ -172,24 +172,6 @@
});
}
- /**
- * This exists to minimize impact into the current HardwareLayer paths as
- * some of the specifics of how to handle error cases in the fully
- * deferred model will work
- */
- @Deprecated
- public void flushChanges() {
- if (HardwareRenderer.sUseRenderThread) {
- // Not supported, don't try.
- return;
- }
-
- boolean success = nFlushChanges(mFinalizer.get());
- if (!success) {
- destroy();
- }
- }
-
public long getLayer() {
return nGetLayer(mFinalizer.get());
}
@@ -216,33 +198,14 @@
return st;
}
- /**
- * This should only be used by HardwareRenderer! Do not call directly
- */
- static HardwareLayer createTextureLayer(HardwareRenderer renderer) {
- return new HardwareLayer(renderer, nCreateTextureLayer(), LAYER_TYPE_TEXTURE);
- }
-
static HardwareLayer adoptTextureLayer(HardwareRenderer renderer, long layer) {
return new HardwareLayer(renderer, layer, LAYER_TYPE_TEXTURE);
}
- /**
- * This should only be used by HardwareRenderer! Do not call directly
- */
- static HardwareLayer createDisplayListLayer(HardwareRenderer renderer,
- int width, int height) {
- return new HardwareLayer(renderer, nCreateRenderLayer(width, height), LAYER_TYPE_DISPLAY_LIST);
- }
-
static HardwareLayer adoptDisplayListLayer(HardwareRenderer renderer, long layer) {
return new HardwareLayer(renderer, layer, LAYER_TYPE_DISPLAY_LIST);
}
- /** This also creates the underlying layer */
- private static native long nCreateTextureLayer();
- private static native long nCreateRenderLayer(int width, int height);
-
private static native void nOnTextureDestroyed(long layerUpdater);
private static native boolean nPrepare(long layerUpdater, int width, int height, boolean isOpaque);
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index d71de9f..d67c974 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -171,9 +171,6 @@
*/
public static boolean sSystemRendererDisabled = false;
- /** @hide */
- public static boolean sUseRenderThread = true;
-
private boolean mEnabled;
private boolean mRequested = true;
@@ -309,7 +306,7 @@
* @hide
*/
public static void setupDiskCache(File cacheDir) {
- GLRenderer.setupShadersDiskCache(new File(cacheDir, CACHE_PATH_SHADERS).getAbsolutePath());
+ ThreadedRenderer.setupShadersDiskCache(new File(cacheDir, CACHE_PATH_SHADERS).getAbsolutePath());
}
/**
@@ -469,11 +466,7 @@
static HardwareRenderer create(boolean translucent) {
HardwareRenderer renderer = null;
if (GLES20Canvas.isAvailable()) {
- if (sUseRenderThread) {
- renderer = new ThreadedRenderer(translucent);
- } else {
- renderer = new GLRenderer(translucent);
- }
+ renderer = new ThreadedRenderer(translucent);
}
return renderer;
}
@@ -500,7 +493,7 @@
* see {@link android.content.ComponentCallbacks}
*/
static void startTrimMemory(int level) {
- GLRenderer.startTrimMemory(level);
+ ThreadedRenderer.startTrimMemory(level);
}
/**
@@ -508,7 +501,7 @@
* cleanup special resources used by the memory trimming process.
*/
static void endTrimMemory() {
- GLRenderer.endTrimMemory();
+ ThreadedRenderer.endTrimMemory();
}
/**
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 11db996..9b3ef7f 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -331,6 +331,14 @@
}
}
+ static void startTrimMemory(int level) {
+ // TODO
+ }
+
+ static void endTrimMemory() {
+ // TODO
+ }
+
private static class AtlasInitializer {
static AtlasInitializer sInstance = new AtlasInitializer();
@@ -367,6 +375,8 @@
}
}
+ static native void setupShadersDiskCache(String cacheFile);
+
private static native void nSetAtlas(GraphicBuffer buffer, long[] map);
private static native long nCreateRootRenderNode();
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index ce266d7..b500e46 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -13593,12 +13593,6 @@
}
}
- // The layer is not valid if the underlying GPU resources cannot be allocated
- mHardwareLayer.flushChanges();
- if (!mHardwareLayer.isValid()) {
- return null;
- }
-
mHardwareLayer.setLayerPaint(mLayerPaint);
RenderNode displayList = mHardwareLayer.startRecording();
updateDisplayListIfDirty(displayList, true);
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index ac25b57..f3d1e3c 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -716,17 +716,6 @@
if (!HardwareRenderer.sRendererDisabled || (HardwareRenderer.sSystemRendererDisabled
&& forceHwAccelerated)) {
- if (!HardwareRenderer.sUseRenderThread) {
- // TODO: Delete
- // Don't enable hardware acceleration when we're not on the main thread
- if (!HardwareRenderer.sSystemRendererDisabled &&
- Looper.getMainLooper() != Looper.myLooper()) {
- Log.w(HardwareRenderer.LOG_TAG, "Attempting to initialize hardware "
- + "acceleration outside of the main thread, aborting");
- return;
- }
- }
-
if (mAttachInfo.mHardwareRenderer != null) {
mAttachInfo.mHardwareRenderer.destroy(true);
}
diff --git a/core/java/com/android/internal/app/IMediaContainerService.aidl b/core/java/com/android/internal/app/IMediaContainerService.aidl
index 03d3b22..77f0dec 100644
--- a/core/java/com/android/internal/app/IMediaContainerService.aidl
+++ b/core/java/com/android/internal/app/IMediaContainerService.aidl
@@ -25,16 +25,18 @@
interface IMediaContainerService {
String copyResourceToContainer(in Uri packageURI, String containerId, String key,
String resFileName, String publicResFileName, boolean isExternal,
- boolean isForwardLocked);
+ boolean isForwardLocked, in String abiOverride);
int copyResource(in Uri packageURI, in ContainerEncryptionParams encryptionParams,
in ParcelFileDescriptor outStream);
- PackageInfoLite getMinimalPackageInfo(in String packagePath, in int flags, in long threshold);
+ PackageInfoLite getMinimalPackageInfo(in String packagePath, in int flags, in long threshold,
+ in String abiOverride);
boolean checkInternalFreeStorage(in Uri fileUri, boolean isForwardLocked, in long threshold);
- boolean checkExternalFreeStorage(in Uri fileUri, boolean isForwardLocked);
+ boolean checkExternalFreeStorage(in Uri fileUri, boolean isForwardLocked, in String abiOverride);
ObbInfo getObbInfo(in String filename);
long calculateDirectorySize(in String directory);
/** Return file system stats: [0] is total bytes, [1] is available bytes */
long[] getFileSystemStats(in String path);
void clearDirectory(in String directory);
- long calculateInstalledSize(in String packagePath, boolean isForwardLocked);
+ long calculateInstalledSize(in String packagePath, boolean isForwardLocked,
+ in String abiOverride);
}
diff --git a/core/java/com/android/internal/content/NativeLibraryHelper.java b/core/java/com/android/internal/content/NativeLibraryHelper.java
index ba419f9..dab3aff 100644
--- a/core/java/com/android/internal/content/NativeLibraryHelper.java
+++ b/core/java/com/android/internal/content/NativeLibraryHelper.java
@@ -20,6 +20,7 @@
import android.util.Slog;
import java.io.File;
+import java.io.IOException;
/**
* Native libraries helper.
@@ -141,4 +142,18 @@
return deletedFiles;
}
+
+ // We don't care about the other return values for now.
+ private static final int BITCODE_PRESENT = 1;
+
+ public static boolean hasRenderscriptBitcode(ApkHandle handle) throws IOException {
+ final int returnVal = hasRenderscriptBitcode(handle.apkHandle);
+ if (returnVal < 0) {
+ throw new IOException("Error scanning APK, code: " + returnVal);
+ }
+
+ return (returnVal == BITCODE_PRESENT);
+ }
+
+ private static native int hasRenderscriptBitcode(long apkHandle);
}
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index f446c3a..a1cd7f7 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -57,7 +57,6 @@
android_view_KeyEvent.cpp \
android_view_KeyCharacterMap.cpp \
android_view_GraphicBuffer.cpp \
- android_view_GLRenderer.cpp \
android_view_GLES20Canvas.cpp \
android_view_HardwareLayer.cpp \
android_view_ThreadedRenderer.cpp \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index e069876..e0c5e96 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -130,7 +130,6 @@
extern int register_android_view_RenderNodeAnimator(JNIEnv* env);
extern int register_android_view_GraphicBuffer(JNIEnv* env);
extern int register_android_view_GLES20Canvas(JNIEnv* env);
-extern int register_android_view_GLRenderer(JNIEnv* env);
extern int register_android_view_HardwareLayer(JNIEnv* env);
extern int register_android_view_ThreadedRenderer(JNIEnv* env);
extern int register_android_view_Surface(JNIEnv* env);
@@ -1214,7 +1213,6 @@
REG_JNI(register_android_view_RenderNodeAnimator),
REG_JNI(register_android_view_GraphicBuffer),
REG_JNI(register_android_view_GLES20Canvas),
- REG_JNI(register_android_view_GLRenderer),
REG_JNI(register_android_view_HardwareLayer),
REG_JNI(register_android_view_ThreadedRenderer),
REG_JNI(register_android_view_Surface),
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index 9141d44..ecdfeb2 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -91,53 +91,9 @@
} gRectClassInfo;
// ----------------------------------------------------------------------------
-// Caching
-// ----------------------------------------------------------------------------
-
-static void android_view_GLES20Canvas_flushCaches(JNIEnv* env, jobject clazz,
- jint mode) {
- if (Caches::hasInstance()) {
- Caches::getInstance().flush(static_cast<Caches::FlushMode>(mode));
- }
-}
-
-static jboolean android_view_GLES20Canvas_initCaches(JNIEnv* env, jobject clazz) {
- if (Caches::hasInstance()) {
- return Caches::getInstance().init() ? JNI_TRUE : JNI_FALSE;
- }
- return JNI_FALSE;
-}
-
-static void android_view_GLES20Canvas_terminateCaches(JNIEnv* env, jobject clazz) {
- if (Caches::hasInstance()) {
- Caches::getInstance().terminate();
- }
-}
-
-// ----------------------------------------------------------------------------
-// Caching
-// ----------------------------------------------------------------------------
-
-static void android_view_GLES20Canvas_initAtlas(JNIEnv* env, jobject clazz,
- jobject graphicBuffer, jlongArray atlasMapArray, jint count) {
-
- sp<GraphicBuffer> buffer = graphicBufferForJavaObject(env, graphicBuffer);
- jlong* jAtlasMap = env->GetLongArrayElements(atlasMapArray, NULL);
- Caches::getInstance().assetAtlas.init(buffer, jAtlasMap, count);
- env->ReleaseLongArrayElements(atlasMapArray, jAtlasMap, 0);
-}
-
-// ----------------------------------------------------------------------------
// Constructors
// ----------------------------------------------------------------------------
-static jlong android_view_GLES20Canvas_createRenderer(JNIEnv* env, jobject clazz) {
- RENDERER_LOGD("Create OpenGLRenderer");
- OpenGLRenderer* renderer = new OpenGLRenderer();
- renderer->initProperties();
- return reinterpret_cast<jlong>(renderer);
-}
-
static void android_view_GLES20Canvas_destroyRenderer(JNIEnv* env, jobject clazz,
jlong rendererPtr) {
OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
@@ -174,10 +130,6 @@
renderer->finish();
}
-static jint android_view_GLES20Canvas_getStencilSize(JNIEnv* env, jobject clazz) {
- return Stencil::getStencilSize();
-}
-
static void android_view_GLES20Canvas_setProperty(JNIEnv* env,
jobject clazz, jstring name, jstring value) {
if (!Caches::hasInstance()) {
@@ -577,15 +529,6 @@
}
}
-static void android_view_GLES20Canvas_drawRects(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jfloatArray rects, jint count, jlong paintPtr) {
- OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
- jfloat* storage = env->GetFloatArrayElements(rects, NULL);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
- renderer->drawRects(storage, count, paint);
- env->ReleaseFloatArrayElements(rects, storage, 0);
-}
-
static void android_view_GLES20Canvas_drawPoints(JNIEnv* env, jobject clazz,
jlong rendererPtr, jfloatArray points, jint offset, jint count, jlong paintPtr) {
OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
@@ -924,39 +867,6 @@
renderer->drawLayer(layer, x, y);
}
-static jboolean android_view_GLES20Canvas_copyLayer(JNIEnv* env, jobject clazz,
- jlong layerPtr, jlong bitmapPtr) {
- Layer* layer = reinterpret_cast<Layer*>(layerPtr);
- SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr);
- return LayerRenderer::copyLayer(layer, bitmap);
-}
-
-static void android_view_GLES20Canvas_pushLayerUpdate(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jlong layerPtr) {
- OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
- Layer* layer = reinterpret_cast<Layer*>(layerPtr);
- renderer->pushLayerUpdate(layer);
-}
-
-static void android_view_GLES20Canvas_cancelLayerUpdate(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jlong layerPtr) {
- OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
- Layer* layer = reinterpret_cast<Layer*>(layerPtr);
- renderer->cancelLayerUpdate(layer);
-}
-
-static void android_view_GLES20Canvas_clearLayerUpdates(JNIEnv* env, jobject clazz,
- jlong rendererPtr) {
- OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
- renderer->clearLayerUpdates();
-}
-
-static void android_view_GLES20Canvas_flushLayerUpdates(JNIEnv* env, jobject clazz,
- jlong rendererPtr) {
- OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
- renderer->flushLayerUpdates();
-}
-
#endif // USE_OPENGL_RENDERER
// ----------------------------------------------------------------------------
@@ -1001,14 +911,7 @@
{ "nIsAvailable", "()Z", (void*) android_view_GLES20Canvas_isAvailable },
#ifdef USE_OPENGL_RENDERER
- { "nFlushCaches", "(I)V", (void*) android_view_GLES20Canvas_flushCaches },
- { "nInitCaches", "()Z", (void*) android_view_GLES20Canvas_initCaches },
- { "nTerminateCaches", "()V", (void*) android_view_GLES20Canvas_terminateCaches },
- { "nInitAtlas", "(Landroid/view/GraphicBuffer;[JI)V",
- (void*) android_view_GLES20Canvas_initAtlas },
-
- { "nCreateRenderer", "()J", (void*) android_view_GLES20Canvas_createRenderer },
{ "nDestroyRenderer", "(J)V", (void*) android_view_GLES20Canvas_destroyRenderer },
{ "nSetViewport", "(JII)V", (void*) android_view_GLES20Canvas_setViewport },
{ "nPrepare", "(JZ)I", (void*) android_view_GLES20Canvas_prepare },
@@ -1017,9 +920,6 @@
{ "nSetProperty", "(Ljava/lang/String;Ljava/lang/String;)V",
(void*) android_view_GLES20Canvas_setProperty },
-
- { "nGetStencilSize", "()I", (void*) android_view_GLES20Canvas_getStencilSize },
-
{ "nCallDrawGLFunction", "(JJ)I", (void*) android_view_GLES20Canvas_callDrawGLFunction },
{ "nSave", "(JI)I", (void*) android_view_GLES20Canvas_save },
@@ -1059,7 +959,6 @@
{ "nDrawColor", "(JII)V", (void*) android_view_GLES20Canvas_drawColor },
{ "nDrawRect", "(JFFFFJ)V", (void*) android_view_GLES20Canvas_drawRect },
{ "nDrawRects", "(JJJ)V", (void*) android_view_GLES20Canvas_drawRegionAsRects },
- { "nDrawRects", "(J[FIJ)V", (void*) android_view_GLES20Canvas_drawRects },
{ "nDrawRoundRect", "(JFFFFFFJ)V", (void*) android_view_GLES20Canvas_drawRoundRect },
{ "nDrawCircle", "(JFFFJ)V", (void*) android_view_GLES20Canvas_drawCircle },
{ "nDrawCircle", "(JJJJJ)V", (void*) android_view_GLES20Canvas_drawCircleProps },
@@ -1099,11 +998,6 @@
{ "nCreateDisplayListRenderer", "()J", (void*) android_view_GLES20Canvas_createDisplayListRenderer },
{ "nDrawLayer", "(JJFF)V", (void*) android_view_GLES20Canvas_drawLayer },
- { "nCopyLayer", "(JJ)Z", (void*) android_view_GLES20Canvas_copyLayer },
- { "nClearLayerUpdates", "(J)V", (void*) android_view_GLES20Canvas_clearLayerUpdates },
- { "nFlushLayerUpdates", "(J)V", (void*) android_view_GLES20Canvas_flushLayerUpdates },
- { "nPushLayerUpdate", "(JJ)V", (void*) android_view_GLES20Canvas_pushLayerUpdate },
- { "nCancelLayerUpdate", "(JJ)V", (void*) android_view_GLES20Canvas_cancelLayerUpdate },
{ "nGetMaximumTextureWidth", "()I", (void*) android_view_GLES20Canvas_getMaxTextureWidth },
{ "nGetMaximumTextureHeight", "()I", (void*) android_view_GLES20Canvas_getMaxTextureHeight },
diff --git a/core/jni/android_view_GLRenderer.cpp b/core/jni/android_view_GLRenderer.cpp
deleted file mode 100644
index d0269a3..0000000
--- a/core/jni/android_view_GLRenderer.cpp
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "GLRenderer"
-
-#include "jni.h"
-#include <nativehelper/JNIHelp.h>
-#include <android_runtime/AndroidRuntime.h>
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-#include <EGL/egl_cache.h>
-
-#include <utils/Timers.h>
-
-#include <private/hwui/DrawGlInfo.h>
-
-#include <Caches.h>
-#include <Extensions.h>
-#include <LayerRenderer.h>
-#include <RenderNode.h>
-
-#ifdef USE_OPENGL_RENDERER
- EGLAPI void EGLAPIENTRY eglBeginFrame(EGLDisplay dpy, EGLSurface surface);
-#endif
-
-namespace android {
-
-/**
- * Note: OpenGLRenderer JNI layer is generated and compiled only on supported
- * devices. This means all the logic must be compiled only when the
- * preprocessor variable USE_OPENGL_RENDERER is defined.
- */
-#ifdef USE_OPENGL_RENDERER
-
-// ----------------------------------------------------------------------------
-// Defines
-// ----------------------------------------------------------------------------
-
-// Debug
-#define DEBUG_RENDERER 0
-
-// Debug
-#if DEBUG_RENDERER
- #define RENDERER_LOGD(...) ALOGD(__VA_ARGS__)
-#else
- #define RENDERER_LOGD(...)
-#endif
-
-// ----------------------------------------------------------------------------
-// Surface and display management
-// ----------------------------------------------------------------------------
-
-static jboolean android_view_GLRenderer_preserveBackBuffer(JNIEnv* env, jobject clazz) {
- EGLDisplay display = eglGetCurrentDisplay();
- EGLSurface surface = eglGetCurrentSurface(EGL_DRAW);
-
- eglGetError();
- eglSurfaceAttrib(display, surface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED);
-
- EGLint error = eglGetError();
- if (error != EGL_SUCCESS) {
- RENDERER_LOGD("Could not enable buffer preserved swap behavior (%x)", error);
- }
-
- return error == EGL_SUCCESS;
-}
-
-static jboolean android_view_GLRenderer_isBackBufferPreserved(JNIEnv* env, jobject clazz) {
- EGLDisplay display = eglGetCurrentDisplay();
- EGLSurface surface = eglGetCurrentSurface(EGL_DRAW);
- EGLint value;
-
- eglGetError();
- eglQuerySurface(display, surface, EGL_SWAP_BEHAVIOR, &value);
-
- EGLint error = eglGetError();
- if (error != EGL_SUCCESS) {
- RENDERER_LOGD("Could not query buffer preserved swap behavior (%x)", error);
- }
-
- return error == EGL_SUCCESS && value == EGL_BUFFER_PRESERVED;
-}
-
-// ----------------------------------------------------------------------------
-// Tracing and debugging
-// ----------------------------------------------------------------------------
-
-static bool android_view_GLRenderer_loadProperties(JNIEnv* env, jobject clazz) {
- if (uirenderer::Caches::hasInstance()) {
- return uirenderer::Caches::getInstance().initProperties();
- }
- return false;
-}
-
-static void android_view_GLRenderer_beginFrame(JNIEnv* env, jobject clazz,
- jintArray size) {
-
- EGLDisplay display = eglGetCurrentDisplay();
- EGLSurface surface = eglGetCurrentSurface(EGL_DRAW);
-
- if (size) {
- EGLint value;
- jint* storage = env->GetIntArrayElements(size, NULL);
-
- eglQuerySurface(display, surface, EGL_WIDTH, &value);
- storage[0] = value;
-
- eglQuerySurface(display, surface, EGL_HEIGHT, &value);
- storage[1] = value;
-
- env->ReleaseIntArrayElements(size, storage, 0);
- }
-
- eglBeginFrame(display, surface);
-}
-
-static jlong android_view_GLRenderer_getSystemTime(JNIEnv* env, jobject clazz) {
- if (uirenderer::Extensions::getInstance().hasNvSystemTime()) {
- return eglGetSystemTimeNV();
- }
- return systemTime(SYSTEM_TIME_MONOTONIC);
-}
-
-static void android_view_GLRenderer_destroyLayer(JNIEnv* env, jobject clazz,
- jlong layerPtr) {
- using namespace android::uirenderer;
- Layer* layer = reinterpret_cast<Layer*>(layerPtr);
- LayerRenderer::destroyLayer(layer);
-}
-
-static void android_view_GLRenderer_prepareTree(JNIEnv* env, jobject clazz,
- jlong renderNodePtr) {
- using namespace android::uirenderer;
- RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
- TreeInfo ignoredInfo;
- renderNode->prepareTree(ignoredInfo);
-}
-
-static void android_view_GLRenderer_invokeFunctor(JNIEnv* env, jobject clazz,
- jlong functorPtr, jboolean hasContext) {
- using namespace android::uirenderer;
- Functor* functor = reinterpret_cast<Functor*>(functorPtr);
- DrawGlInfo::Mode mode = hasContext ? DrawGlInfo::kModeProcess : DrawGlInfo::kModeProcessNoContext;
- (*functor)(mode, NULL);
-}
-
-#endif // USE_OPENGL_RENDERER
-
-// ----------------------------------------------------------------------------
-// Shaders
-// ----------------------------------------------------------------------------
-
-static void android_view_GLRenderer_setupShadersDiskCache(JNIEnv* env, jobject clazz,
- jstring diskCachePath) {
-
- const char* cacheArray = env->GetStringUTFChars(diskCachePath, NULL);
- egl_cache_t::get()->setCacheFilename(cacheArray);
- env->ReleaseStringUTFChars(diskCachePath, cacheArray);
-}
-
-// ----------------------------------------------------------------------------
-// JNI Glue
-// ----------------------------------------------------------------------------
-
-const char* const kClassPathName = "android/view/GLRenderer";
-
-static JNINativeMethod gMethods[] = {
-#ifdef USE_OPENGL_RENDERER
- { "isBackBufferPreserved", "()Z", (void*) android_view_GLRenderer_isBackBufferPreserved },
- { "preserveBackBuffer", "()Z", (void*) android_view_GLRenderer_preserveBackBuffer },
- { "loadProperties", "()Z", (void*) android_view_GLRenderer_loadProperties },
-
- { "beginFrame", "([I)V", (void*) android_view_GLRenderer_beginFrame },
-
- { "getSystemTime", "()J", (void*) android_view_GLRenderer_getSystemTime },
- { "nDestroyLayer", "(J)V", (void*) android_view_GLRenderer_destroyLayer },
- { "nPrepareTree", "(J)V", (void*) android_view_GLRenderer_prepareTree },
- { "nInvokeFunctor", "(JZ)V", (void*) android_view_GLRenderer_invokeFunctor },
-#endif
-
- { "setupShadersDiskCache", "(Ljava/lang/String;)V",
- (void*) android_view_GLRenderer_setupShadersDiskCache },
-};
-
-int register_android_view_GLRenderer(JNIEnv* env) {
- return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
-}
-
-};
diff --git a/core/jni/android_view_HardwareLayer.cpp b/core/jni/android_view_HardwareLayer.cpp
index 33a2705..879836d 100644
--- a/core/jni/android_view_HardwareLayer.cpp
+++ b/core/jni/android_view_HardwareLayer.cpp
@@ -43,21 +43,6 @@
#ifdef USE_OPENGL_RENDERER
-static jlong android_view_HardwareLayer_createTextureLayer(JNIEnv* env, jobject clazz) {
- Layer* layer = LayerRenderer::createTextureLayer();
- if (!layer) return 0;
-
- return reinterpret_cast<jlong>( new DeferredLayerUpdater(layer) );
-}
-
-static jlong android_view_HardwareLayer_createRenderLayer(JNIEnv* env, jobject clazz,
- jint width, jint height) {
- Layer* layer = LayerRenderer::createRenderLayer(width, height);
- if (!layer) return 0;
-
- return reinterpret_cast<jlong>( new DeferredLayerUpdater(layer) );
-}
-
static void android_view_HardwareLayer_onTextureDestroyed(JNIEnv* env, jobject clazz,
jlong layerUpdaterPtr) {
DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerUpdaterPtr);
@@ -140,8 +125,6 @@
static JNINativeMethod gMethods[] = {
#ifdef USE_OPENGL_RENDERER
- { "nCreateTextureLayer", "()J", (void*) android_view_HardwareLayer_createTextureLayer },
- { "nCreateRenderLayer", "(II)J", (void*) android_view_HardwareLayer_createRenderLayer },
{ "nOnTextureDestroyed", "(J)V", (void*) android_view_HardwareLayer_onTextureDestroyed },
{ "nPrepare", "(JIIZ)Z", (void*) android_view_HardwareLayer_prepare },
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp
index 1397131..a550649 100644
--- a/core/jni/android_view_ThreadedRenderer.cpp
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -22,6 +22,10 @@
#include <nativehelper/JNIHelp.h>
#include <android_runtime/AndroidRuntime.h>
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <EGL/egl_cache.h>
+
#include <utils/StrongPointer.h>
#include <android_runtime/android_view_Surface.h>
#include <system/window.h>
@@ -329,6 +333,18 @@
#endif
// ----------------------------------------------------------------------------
+// Shaders
+// ----------------------------------------------------------------------------
+
+static void android_view_ThreadedRenderer_setupShadersDiskCache(JNIEnv* env, jobject clazz,
+ jstring diskCachePath) {
+
+ const char* cacheArray = env->GetStringUTFChars(diskCachePath, NULL);
+ egl_cache_t::get()->setCacheFilename(cacheArray);
+ env->ReleaseStringUTFChars(diskCachePath, cacheArray);
+}
+
+// ----------------------------------------------------------------------------
// JNI Glue
// ----------------------------------------------------------------------------
@@ -361,6 +377,8 @@
{ "nNotifyFramePending", "(J)V", (void*) android_view_ThreadedRenderer_notifyFramePending },
{ "nDumpProfileInfo", "(JLjava/io/FileDescriptor;)V", (void*) android_view_ThreadedRenderer_dumpProfileInfo },
#endif
+ { "setupShadersDiskCache", "(Ljava/lang/String;)V",
+ (void*) android_view_ThreadedRenderer_setupShadersDiskCache },
};
int register_android_view_ThreadedRenderer(JNIEnv* env) {
diff --git a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
index 230658f..e55e4ea 100644
--- a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
+++ b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
@@ -46,6 +46,9 @@
#define LIB_SUFFIX ".so"
#define LIB_SUFFIX_LEN (sizeof(LIB_SUFFIX) - 1)
+#define RS_BITCODE_SUFFIX ".bc"
+#define RS_BITCODE_SUFFIX_LEN (sizeof(RS_BITCODE_SUFFIX) -1)
+
#define GDBSERVER "gdbserver"
#define GDBSERVER_LEN (sizeof(GDBSERVER) - 1)
@@ -486,6 +489,42 @@
return (jint) findSupportedAbi(env, apkHandle, javaCpuAbisToSearch);
}
+enum bitcode_scan_result_t {
+ APK_SCAN_ERROR = -1,
+ NO_BITCODE_PRESENT = 0,
+ BITCODE_PRESENT = 1,
+};
+
+static jint
+com_android_internal_content_NativeLibraryHelper_hasRenderscriptBitcode(JNIEnv *env, jclass clazz,
+ jlong apkHandle) {
+ ZipFileRO* zipFile = reinterpret_cast<ZipFileRO*>(apkHandle);
+ void* cookie = NULL;
+ if (!zipFile->startIteration(&cookie)) {
+ return APK_SCAN_ERROR;
+ }
+
+ char fileName[PATH_MAX];
+ ZipEntryRO next = NULL;
+ while ((next = zipFile->nextEntry(cookie)) != NULL) {
+ if (zipFile->getEntryFileName(next, fileName, sizeof(fileName))) {
+ continue;
+ }
+
+ const size_t fileNameLen = strlen(fileName);
+ const char* lastSlash = strrchr(fileName, '/');
+ const char* baseName = (lastSlash == NULL) ? fileName : fileName + 1;
+ if (!strncmp(fileName + fileNameLen - RS_BITCODE_SUFFIX_LEN, RS_BITCODE_SUFFIX,
+ RS_BITCODE_SUFFIX_LEN) && isFilenameSafe(baseName)) {
+ zipFile->endIteration(cookie);
+ return BITCODE_PRESENT;
+ }
+ }
+
+ zipFile->endIteration(cookie);
+ return NO_BITCODE_PRESENT;
+}
+
static jlong
com_android_internal_content_NativeLibraryHelper_openApk(JNIEnv *env, jclass, jstring apkPath)
{
@@ -517,6 +556,8 @@
{"nativeFindSupportedAbi",
"(J[Ljava/lang/String;)I",
(void *)com_android_internal_content_NativeLibraryHelper_findSupportedAbi},
+ {"hasRenderscriptBitcode", "(J)I",
+ (void *)com_android_internal_content_NativeLibraryHelper_hasRenderscriptBitcode},
};
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index bb6a1cb..fe703b2 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2076,7 +2076,7 @@
android:description="@string/permdesc_bindRemoteDisplay"
android:protectionLevel="signature" />
- <!-- Must be required by a {@link android.tv.TvInputService}
+ <!-- Must be required by a {@link android.media.tv.TvInputService}
to ensure that only the system can bind to it. -->
<permission android:name="android.permission.BIND_TV_INPUT"
android:label="@string/permlab_bindTvInput"
diff --git a/core/res/res/drawable-hdpi/work_icon.png b/core/res/res/drawable-hdpi/work_icon.png
index e90866b..be8a36e 100644
--- a/core/res/res/drawable-hdpi/work_icon.png
+++ b/core/res/res/drawable-hdpi/work_icon.png
Binary files differ
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 489adb4..f1f1802 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -4806,6 +4806,8 @@
<attr name="scaleX" />
<!-- The amount to scale the group on X coordinate -->
<attr name="scaleY" />
+ <!-- The alpha of the group (0 is transparent and 1 is opaque) -->
+ <attr name="alpha" />
</declare-styleable>
<!-- Defines the path used in Vector Drawables. -->
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 7234911..9ff67b4 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -457,10 +457,10 @@
<string name="android_system_label">Android System</string>
<!-- Label for the user owner in the intent forwarding app. -->
- <string name="user_owner_label">Personal</string>
+ <string name="user_owner_label">Personal apps</string>
<!-- Label for a corporate profile in the intent forwarding app. -->
- <string name="managed_profile_label">Work</string>
+ <string name="managed_profile_label">Android for Work</string>
<!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permgrouplab_costMoney">Services that cost you money</string>
diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java
index afd529c..304502e 100644
--- a/graphics/java/android/graphics/drawable/VectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/VectorDrawable.java
@@ -40,6 +40,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
+import java.util.Stack;
/**
* This lets you create a drawable based on an XML vector graphic It can be
@@ -129,6 +130,8 @@
private static final int LINEJOIN_ROUND = 1;
private static final int LINEJOIN_BEVEL = 2;
+ private static final boolean DBG_VECTOR_DRAWABLE = false;
+
private final VectorDrawableState mVectorState;
private int mAlpha = 0xFF;
@@ -279,12 +282,17 @@
boolean noGroupTag = true;
boolean noPathTag = true;
- VGroup currentGroup = new VGroup();
+ // Use a stack to help to build the group tree.
+ // The top of the stack is always the current group.
+ final Stack<VGroup> groupStack = new Stack<VGroup>();
+ groupStack.push(pathRenderer.mRootGroup);
int eventType = parser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_TAG) {
final String tagName = parser.getName();
+ final VGroup currentGroup = groupStack.peek();
+
if (SHAPE_PATH.equals(tagName)) {
final VPath path = new VPath();
path.inflate(res, attrs, theme);
@@ -297,18 +305,24 @@
pathRenderer.parseViewport(res, attrs);
noViewportTag = false;
} else if (SHAPE_GROUP.equals(tagName)) {
- currentGroup = new VGroup();
- currentGroup.inflate(res, attrs, theme);
- pathRenderer.mGroupList.add(currentGroup);
+ VGroup newChildGroup = new VGroup();
+ newChildGroup.inflate(res, attrs, theme);
+ currentGroup.mChildGroupList.add(newChildGroup);
+ groupStack.push(newChildGroup);
noGroupTag = false;
}
+ } else if (eventType == XmlPullParser.END_TAG) {
+ final String tagName = parser.getName();
+ if (SHAPE_GROUP.equals(tagName)) {
+ groupStack.pop();
+ }
}
-
eventType = parser.next();
}
- if (noGroupTag && !noPathTag) {
- pathRenderer.mGroupList.add(currentGroup);
+ // Print the tree out for debug.
+ if (DBG_VECTOR_DRAWABLE) {
+ printGroupTree(pathRenderer.mRootGroup, 0);
}
if (noSizeTag || noViewportTag || noPathTag) {
@@ -338,6 +352,21 @@
return pathRenderer;
}
+ private void printGroupTree(VGroup currentGroup, int level) {
+ String indent = "";
+ for (int i = 0 ; i < level ; i++) {
+ indent += " ";
+ }
+ // Print the current node
+ Log.v(LOGTAG, indent + "current group is :" + currentGroup.getName()
+ + " rotation is " + currentGroup.mRotate);
+ Log.v(LOGTAG, indent + "matrix is :" + currentGroup.getLocalMatrix().toString());
+ // Then print all the children
+ for (int i = 0 ; i < currentGroup.mChildGroupList.size(); i++) {
+ printGroupTree(currentGroup.mChildGroupList.get(i), level + 1);
+ }
+ }
+
private void setPathRenderer(VPathRenderer pathRenderer) {
mVectorState.mVPathRenderer = pathRenderer;
}
@@ -350,6 +379,7 @@
public VectorDrawableState(VectorDrawableState copy) {
if (copy != null) {
mChangingConfigurations = copy.mChangingConfigurations;
+ // TODO: Make sure the constant state are handled correctly.
mVPathRenderer = new VPathRenderer(copy.mVPathRenderer);
mPadding = new Rect(copy.mPadding);
}
@@ -377,28 +407,42 @@
}
private static class VPathRenderer {
+ /* Right now the internal data structure is organized as a tree.
+ * Each node can be a group node, or a path.
+ * A group node can have groups or paths as children, but a path node has
+ * no children.
+ * One example can be:
+ * Root Group
+ * / | \
+ * Group Path Group
+ * / \ |
+ * Path Path Path
+ *
+ */
+ private final VGroup mRootGroup;
+
private final Path mPath = new Path();
private final Path mRenderPath = new Path();
- private final Matrix mMatrix = new Matrix();
+ private static final Matrix IDENTITY_MATRIX = new Matrix();
private Paint mStrokePaint;
private Paint mFillPaint;
private ColorFilter mColorFilter;
private PathMeasure mPathMeasure;
- final ArrayList<VGroup> mGroupList = new ArrayList<VGroup>();
+ private float mBaseWidth = 0;
+ private float mBaseHeight = 0;
+ private float mViewportWidth = 0;
+ private float mViewportHeight = 0;
- float mBaseWidth = 0;
- float mBaseHeight = 0;
- float mViewportWidth = 0;
- float mViewportHeight = 0;
+ private final Matrix mFinalPathMatrix = new Matrix();
public VPathRenderer() {
+ mRootGroup = new VGroup();
}
public VPathRenderer(VPathRenderer copy) {
- mGroupList.addAll(copy.mGroupList);
-
+ mRootGroup = copy.mRootGroup;
mBaseWidth = copy.mBaseWidth;
mBaseHeight = copy.mBaseHeight;
mViewportWidth = copy.mViewportHeight;
@@ -406,33 +450,59 @@
}
public boolean canApplyTheme() {
- final ArrayList<VGroup> groups = mGroupList;
- for (int i = groups.size() - 1; i >= 0; i--) {
- final ArrayList<VPath> paths = groups.get(i).mVGList;
- for (int j = paths.size() - 1; j >= 0; j--) {
- final VPath path = paths.get(j);
- if (path.canApplyTheme()) {
- return true;
- }
+ // If one of the paths can apply theme, then return true;
+ return recursiveCanApplyTheme(mRootGroup);
+ }
+
+ private boolean recursiveCanApplyTheme(VGroup currentGroup) {
+ // We can do a tree traverse here, if there is one path return true,
+ // then we return true for the whole tree.
+ final ArrayList<VPath> paths = currentGroup.mPathList;
+ for (int j = paths.size() - 1; j >= 0; j--) {
+ final VPath path = paths.get(j);
+ if (path.canApplyTheme()) {
+ return true;
}
}
+ final ArrayList<VGroup> childGroups = currentGroup.mChildGroupList;
+
+ for (int i = 0; i < childGroups.size(); i++) {
+ VGroup childGroup = childGroups.get(i);
+ if (childGroup.canApplyTheme()
+ || recursiveCanApplyTheme(childGroup)) {
+ return true;
+ }
+ }
return false;
}
public void applyTheme(Theme t) {
- final ArrayList<VGroup> groups = mGroupList;
- for (int i = groups.size() - 1; i >= 0; i--) {
- VGroup currentGroup = groups.get(i);
- currentGroup.applyTheme(t);
- final ArrayList<VPath> paths = currentGroup.mVGList;
- for (int j = paths.size() - 1; j >= 0; j--) {
- final VPath path = paths.get(j);
- if (path.canApplyTheme()) {
- path.applyTheme(t);
- }
+ // Apply theme to every path of the tree.
+ recursiveApplyTheme(mRootGroup, t);
+ }
+
+ private void recursiveApplyTheme(VGroup currentGroup, Theme t) {
+ // We can do a tree traverse here, apply theme to all paths which
+ // can apply theme.
+ final ArrayList<VPath> paths = currentGroup.mPathList;
+ for (int j = paths.size() - 1; j >= 0; j--) {
+ final VPath path = paths.get(j);
+ if (path.canApplyTheme()) {
+ path.applyTheme(t);
}
}
+
+ final ArrayList<VGroup> childGroups = currentGroup.mChildGroupList;
+
+ for (int i = 0; i < childGroups.size(); i++) {
+ VGroup childGroup = childGroups.get(i);
+ if (childGroup.canApplyTheme()) {
+ childGroup.applyTheme(t);
+ }
+ recursiveApplyTheme(childGroup, t);
+ }
+
}
public void setColorFilter(ColorFilter colorFilter) {
@@ -448,34 +518,35 @@
}
- public void draw(Canvas canvas, int w, int h) {
- if (mGroupList == null || mGroupList.size() == 0) {
- Log.e(LOGTAG,"There is no group to draw");
- return;
- }
+ private void drawGroupTree(VGroup currentGroup, Matrix currentMatrix,
+ Canvas canvas, int w, int h) {
+ // Calculate current group's matrix by preConcat the parent's and
+ // and the current one on the top of the stack.
+ // Basically the Mfinal = Mviewport * M0 * M1 * M2;
+ // Mi the local matrix at level i of the group tree.
+ currentGroup.mStackedMatrix.set(currentMatrix);
- for (int i = 0; i < mGroupList.size(); i++) {
- VGroup currentGroup = mGroupList.get(i);
- if (currentGroup != null) {
- drawPath(currentGroup, canvas, w, h);
- }
+ currentGroup.mStackedMatrix.preConcat(currentGroup.mLocalMatrix);
+
+ drawPath(currentGroup, canvas, w, h);
+ // Draw the group tree in post order.
+ for (int i = 0 ; i < currentGroup.mChildGroupList.size(); i++) {
+ drawGroupTree(currentGroup.mChildGroupList.get(i),
+ currentGroup.mStackedMatrix, canvas, w, h);
}
}
+ public void draw(Canvas canvas, int w, int h) {
+ // Travese the tree in pre-order to draw.
+ drawGroupTree(mRootGroup, IDENTITY_MATRIX, canvas, w, h);
+ }
+
private void drawPath(VGroup vGroup, Canvas canvas, int w, int h) {
final float scale = Math.min(h / mViewportHeight, w / mViewportWidth);
- mMatrix.reset();
-
- // The order we apply is the same as the
- // RenderNode.cpp::applyViewPropertyTransforms().
- mMatrix.postTranslate(-vGroup.mPivotX, -vGroup.mPivotY);
- mMatrix.postScale(vGroup.mScaleX, vGroup.mScaleY);
- mMatrix.postRotate(vGroup.mRotate, 0, 0);
- mMatrix.postTranslate(vGroup.mTranslateX + vGroup.mPivotX, vGroup.mTranslateY + vGroup.mPivotY);
-
- mMatrix.postScale(scale, scale, mViewportWidth / 2f, mViewportHeight / 2f);
- mMatrix.postTranslate(w / 2f - mViewportWidth / 2f, h / 2f - mViewportHeight / 2f);
+ mFinalPathMatrix.set(vGroup.mStackedMatrix);
+ mFinalPathMatrix.postScale(scale, scale, mViewportWidth / 2f, mViewportHeight / 2f);
+ mFinalPathMatrix.postTranslate(w / 2f - mViewportWidth / 2f, h / 2f - mViewportHeight / 2f);
ArrayList<VPath> paths = vGroup.getPaths();
for (int i = 0; i < paths.size(); i++) {
@@ -507,7 +578,7 @@
mRenderPath.reset();
- mRenderPath.addPath(path, mMatrix);
+ mRenderPath.addPath(path, mFinalPathMatrix);
if (vPath.mClip) {
canvas.clipPath(mRenderPath, Region.Op.REPLACE);
@@ -588,7 +659,8 @@
private static class VGroup {
private final HashMap<String, VPath> mVGPathMap = new HashMap<String, VPath>();
- private final ArrayList<VPath> mVGList = new ArrayList<VPath>();
+ private final ArrayList<VPath> mPathList = new ArrayList<VPath>();
+ private final ArrayList<VGroup> mChildGroupList = new ArrayList<VGroup>();
private float mRotate = 0;
private float mPivotX = 0;
@@ -597,15 +669,36 @@
private float mScaleY = 1;
private float mTranslateX = 0;
private float mTranslateY = 0;
+ private float mAlpha = 1;
+
+ // mLocalMatrix is parsed from the XML.
+ private final Matrix mLocalMatrix = new Matrix();
+ // mStackedMatrix is only used when drawing, it combines all the
+ // parents' local matrices with the current one.
+ private final Matrix mStackedMatrix = new Matrix();
private int[] mThemeAttrs;
+ private String mName = null;
+
+ public String getName() {
+ return mName;
+ }
+
+ public Matrix getLocalMatrix() {
+ return mLocalMatrix;
+ }
+
public void add(VPath path) {
String id = path.getID();
mVGPathMap.put(id, path);
- mVGList.add(path);
+ mPathList.add(path);
}
+ public boolean canApplyTheme() {
+ return mThemeAttrs != null;
+ }
+
public void applyTheme(Theme t) {
if (mThemeAttrs == null) {
return;
@@ -621,6 +714,11 @@
mScaleY = a.getFloat(R.styleable.VectorDrawableGroup_scaleY, mScaleY);
mTranslateX = a.getFloat(R.styleable.VectorDrawableGroup_translateX, mTranslateX);
mTranslateY = a.getFloat(R.styleable.VectorDrawableGroup_translateY, mTranslateY);
+ mAlpha = a.getFloat(R.styleable.VectorDrawableGroup_alpha, mAlpha);
+ updateLocalMatrix();
+ if (a.hasValue(R.styleable.VectorDrawableGroup_name)) {
+ mName = a.getString(R.styleable.VectorDrawableGroup_name);
+ }
a.recycle();
}
@@ -660,15 +758,34 @@
mTranslateY = a.getFloat(R.styleable.VectorDrawableGroup_translateY, mTranslateY);
}
+ if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawableGroup_name] == 0) {
+ mName = a.getString(R.styleable.VectorDrawableGroup_name);
+ }
+
+ if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawableGroup_alpha] == 0) {
+ mAlpha = a.getFloat(R.styleable.VectorDrawableGroup_alpha, mAlpha);
+ }
+
+ updateLocalMatrix();
a.recycle();
}
+ private void updateLocalMatrix() {
+ // The order we apply is the same as the
+ // RenderNode.cpp::applyViewPropertyTransforms().
+ mLocalMatrix.reset();
+ mLocalMatrix.postTranslate(-mPivotX, -mPivotY);
+ mLocalMatrix.postScale(mScaleX, mScaleY);
+ mLocalMatrix.postRotate(mRotate, 0, 0);
+ mLocalMatrix.postTranslate(mTranslateX + mPivotX, mTranslateY + mPivotY);
+ }
+
/**
* Must return in order of adding
* @return ordered list of paths
*/
public ArrayList<VPath> getPaths() {
- return mVGList;
+ return mPathList;
}
}
diff --git a/core/java/android/tv/ITvInputClient.aidl b/media/java/android/media/tv/ITvInputClient.aidl
similarity index 94%
rename from core/java/android/tv/ITvInputClient.aidl
rename to media/java/android/media/tv/ITvInputClient.aidl
index ef89c68..dc79a73 100644
--- a/core/java/android/tv/ITvInputClient.aidl
+++ b/media/java/android/media/tv/ITvInputClient.aidl
@@ -14,11 +14,11 @@
* limitations under the License.
*/
-package android.tv;
+package android.media.tv;
import android.content.ComponentName;
+import android.media.tv.ITvInputSession;
import android.os.Bundle;
-import android.tv.ITvInputSession;
import android.view.InputChannel;
/**
diff --git a/core/java/android/tv/ITvInputHardware.aidl b/media/java/android/media/tv/ITvInputHardware.aidl
similarity index 95%
rename from core/java/android/tv/ITvInputHardware.aidl
rename to media/java/android/media/tv/ITvInputHardware.aidl
index 7250453..f35e8f3 100644
--- a/core/java/android/tv/ITvInputHardware.aidl
+++ b/media/java/android/media/tv/ITvInputHardware.aidl
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-package android.tv;
+package android.media.tv;
-import android.tv.TvStreamConfig;
+import android.media.tv.TvStreamConfig;
import android.view.KeyEvent;
import android.view.Surface;
diff --git a/core/java/android/tv/ITvInputHardwareCallback.aidl b/media/java/android/media/tv/ITvInputHardwareCallback.aidl
similarity index 91%
rename from core/java/android/tv/ITvInputHardwareCallback.aidl
rename to media/java/android/media/tv/ITvInputHardwareCallback.aidl
index 83041be..870883b 100644
--- a/core/java/android/tv/ITvInputHardwareCallback.aidl
+++ b/media/java/android/media/tv/ITvInputHardwareCallback.aidl
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-package android.tv;
+package android.media.tv;
-import android.tv.TvStreamConfig;
+import android.media.tv.TvStreamConfig;
/**
* @hide
diff --git a/core/java/android/tv/ITvInputManager.aidl b/media/java/android/media/tv/ITvInputManager.aidl
similarity index 89%
rename from core/java/android/tv/ITvInputManager.aidl
rename to media/java/android/media/tv/ITvInputManager.aidl
index c6f8d79..6db5a18 100644
--- a/core/java/android/tv/ITvInputManager.aidl
+++ b/media/java/android/media/tv/ITvInputManager.aidl
@@ -14,16 +14,16 @@
* limitations under the License.
*/
-package android.tv;
+package android.media.tv;
import android.content.ComponentName;
import android.graphics.Rect;
+import android.media.tv.ITvInputHardware;
+import android.media.tv.ITvInputHardwareCallback;
+import android.media.tv.ITvInputClient;
+import android.media.tv.TvInputHardwareInfo;
+import android.media.tv.TvInputInfo;
import android.net.Uri;
-import android.tv.ITvInputHardware;
-import android.tv.ITvInputHardwareCallback;
-import android.tv.ITvInputClient;
-import android.tv.TvInputHardwareInfo;
-import android.tv.TvInputInfo;
import android.view.Surface;
/**
diff --git a/core/java/android/tv/ITvInputService.aidl b/media/java/android/media/tv/ITvInputService.aidl
similarity index 88%
rename from core/java/android/tv/ITvInputService.aidl
rename to media/java/android/media/tv/ITvInputService.aidl
index 4f1bc2b..992e424 100644
--- a/core/java/android/tv/ITvInputService.aidl
+++ b/media/java/android/media/tv/ITvInputService.aidl
@@ -14,10 +14,10 @@
* limitations under the License.
*/
-package android.tv;
+package android.media.tv;
-import android.tv.ITvInputServiceCallback;
-import android.tv.ITvInputSessionCallback;
+import android.media.tv.ITvInputServiceCallback;
+import android.media.tv.ITvInputSessionCallback;
import android.view.InputChannel;
/**
diff --git a/core/java/android/tv/ITvInputServiceCallback.aidl b/media/java/android/media/tv/ITvInputServiceCallback.aidl
similarity index 96%
rename from core/java/android/tv/ITvInputServiceCallback.aidl
rename to media/java/android/media/tv/ITvInputServiceCallback.aidl
index 71fc780..c9484dd 100644
--- a/core/java/android/tv/ITvInputServiceCallback.aidl
+++ b/media/java/android/media/tv/ITvInputServiceCallback.aidl
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.tv;
+package android.media.tv;
import android.content.ComponentName;
diff --git a/core/java/android/tv/ITvInputSession.aidl b/media/java/android/media/tv/ITvInputSession.aidl
similarity index 97%
rename from core/java/android/tv/ITvInputSession.aidl
rename to media/java/android/media/tv/ITvInputSession.aidl
index 32fee4b..fb2e251 100644
--- a/core/java/android/tv/ITvInputSession.aidl
+++ b/media/java/android/media/tv/ITvInputSession.aidl
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.tv;
+package android.media.tv;
import android.graphics.Rect;
import android.net.Uri;
diff --git a/core/java/android/tv/ITvInputSessionCallback.aidl b/media/java/android/media/tv/ITvInputSessionCallback.aidl
similarity index 93%
rename from core/java/android/tv/ITvInputSessionCallback.aidl
rename to media/java/android/media/tv/ITvInputSessionCallback.aidl
index e27b8bf..71f2d07 100644
--- a/core/java/android/tv/ITvInputSessionCallback.aidl
+++ b/media/java/android/media/tv/ITvInputSessionCallback.aidl
@@ -14,10 +14,10 @@
* limitations under the License.
*/
-package android.tv;
+package android.media.tv;
+import android.media.tv.ITvInputSession;
import android.os.Bundle;
-import android.tv.ITvInputSession;
/**
* Helper interface for ITvInputSession to allow the TV input to notify the system service when a
diff --git a/core/java/android/tv/ITvInputSessionWrapper.java b/media/java/android/media/tv/ITvInputSessionWrapper.java
similarity index 96%
rename from core/java/android/tv/ITvInputSessionWrapper.java
rename to media/java/android/media/tv/ITvInputSessionWrapper.java
index 3ccccf3..975e391 100644
--- a/core/java/android/tv/ITvInputSessionWrapper.java
+++ b/media/java/android/media/tv/ITvInputSessionWrapper.java
@@ -14,22 +14,20 @@
* limitations under the License.
*/
-package android.tv;
+package android.media.tv;
import android.content.Context;
import android.graphics.Rect;
+import android.media.tv.TvInputManager.Session;
+import android.media.tv.TvInputService.TvInputSessionImpl;
import android.net.Uri;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
-import android.tv.TvInputManager.Session;
-import android.tv.TvInputService.TvInputSessionImpl;
import android.util.Log;
import android.view.InputChannel;
import android.view.InputEvent;
import android.view.InputEventReceiver;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
import android.view.Surface;
import com.android.internal.os.HandlerCaller;
diff --git a/core/java/android/provider/TvContract.java b/media/java/android/media/tv/TvContract.java
similarity index 98%
rename from core/java/android/provider/TvContract.java
rename to media/java/android/media/tv/TvContract.java
index 0d90a16..e9a87ff 100644
--- a/core/java/android/provider/TvContract.java
+++ b/media/java/android/media/tv/TvContract.java
@@ -14,13 +14,13 @@
* limitations under the License.
*/
-package android.provider;
+package android.media.tv;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.net.Uri;
-import android.tv.TvInputService;
+import android.provider.BaseColumns;
import java.util.List;
@@ -88,8 +88,8 @@
/**
* Builds a URI that points to all browsable channels from a given TV input.
*
- * @param name {@link ComponentName} of the {@link android.tv.TvInputService} that implements
- * the given TV input.
+ * @param name {@link ComponentName} of the {@link android.media.tv.TvInputService} that
+ * implements the given TV input.
*/
public static final Uri buildChannelsUriForInput(ComponentName name) {
return buildChannelsUriForInput(name, true);
@@ -98,8 +98,8 @@
/**
* Builds a URI that points to all or browsable-only channels from a given TV input.
*
- * @param name {@link ComponentName} of the {@link android.tv.TvInputService} that implements
- * the given TV input.
+ * @param name {@link ComponentName} of the {@link android.media.tv.TvInputService} that
+ * implements the given TV input.
* @param browsableOnly If set to {@code true} the URI points to only browsable channels. If set
* to {@code false} the URI points to all channels regardless of whether they are
* browsable or not.
diff --git a/core/java/android/tv/TvInputHardwareInfo.aidl b/media/java/android/media/tv/TvInputHardwareInfo.aidl
similarity index 95%
rename from core/java/android/tv/TvInputHardwareInfo.aidl
rename to media/java/android/media/tv/TvInputHardwareInfo.aidl
index 484ab60..a4c38bb 100644
--- a/core/java/android/tv/TvInputHardwareInfo.aidl
+++ b/media/java/android/media/tv/TvInputHardwareInfo.aidl
@@ -15,6 +15,6 @@
* limitations under the License.
*/
-package android.tv;
+package android.media.tv;
parcelable TvInputHardwareInfo;
diff --git a/core/java/android/tv/TvInputHardwareInfo.java b/media/java/android/media/tv/TvInputHardwareInfo.java
similarity index 98%
rename from core/java/android/tv/TvInputHardwareInfo.java
rename to media/java/android/media/tv/TvInputHardwareInfo.java
index b0dc58e..4beb960 100644
--- a/core/java/android/tv/TvInputHardwareInfo.java
+++ b/media/java/android/media/tv/TvInputHardwareInfo.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.tv;
+package android.media.tv;
import android.os.Parcel;
import android.os.Parcelable;
diff --git a/core/java/android/tv/TvInputInfo.aidl b/media/java/android/media/tv/TvInputInfo.aidl
similarity index 95%
rename from core/java/android/tv/TvInputInfo.aidl
rename to media/java/android/media/tv/TvInputInfo.aidl
index abc4b47..ba139a2 100644
--- a/core/java/android/tv/TvInputInfo.aidl
+++ b/media/java/android/media/tv/TvInputInfo.aidl
@@ -14,6 +14,6 @@
* limitations under the License.
*/
-package android.tv;
+package android.media.tv;
parcelable TvInputInfo;
diff --git a/core/java/android/tv/TvInputInfo.java b/media/java/android/media/tv/TvInputInfo.java
similarity index 98%
rename from core/java/android/tv/TvInputInfo.java
rename to media/java/android/media/tv/TvInputInfo.java
index 217e4b7..854fea7 100644
--- a/core/java/android/tv/TvInputInfo.java
+++ b/media/java/android/media/tv/TvInputInfo.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.tv;
+package android.media.tv;
import android.content.ComponentName;
import android.content.pm.PackageManager;
diff --git a/core/java/android/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java
similarity index 99%
rename from core/java/android/tv/TvInputManager.java
rename to media/java/android/media/tv/TvInputManager.java
index d0c2ca6..1335a1b 100644
--- a/core/java/android/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.tv;
+package android.media.tv;
import android.graphics.Rect;
import android.net.Uri;
diff --git a/core/java/android/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java
similarity index 98%
rename from core/java/android/tv/TvInputService.java
rename to media/java/android/media/tv/TvInputService.java
index 03d24db..a3b0273 100644
--- a/core/java/android/tv/TvInputService.java
+++ b/media/java/android/media/tv/TvInputService.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.tv;
+package android.media.tv;
import android.app.Service;
import android.content.ComponentName;
@@ -22,6 +22,8 @@
import android.content.Intent;
import android.graphics.PixelFormat;
import android.graphics.Rect;
+import android.media.tv.ITvInputService;
+import android.media.tv.TvInputManager.Session;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
@@ -29,7 +31,6 @@
import android.os.Message;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
-import android.tv.TvInputManager.Session;
import android.util.Log;
import android.view.Gravity;
import android.view.InputChannel;
@@ -59,7 +60,7 @@
* must also require the {@link android.Manifest.permission#BIND_TV_INPUT} permission so that
* other applications cannot abuse it.
*/
- public static final String SERVICE_INTERFACE = "android.tv.TvInputService";
+ public static final String SERVICE_INTERFACE = "android.media.tv.TvInputService";
private String mId;
private final Handler mHandler = new ServiceHandler();
diff --git a/core/java/android/tv/TvStreamConfig.aidl b/media/java/android/media/tv/TvStreamConfig.aidl
similarity index 95%
rename from core/java/android/tv/TvStreamConfig.aidl
rename to media/java/android/media/tv/TvStreamConfig.aidl
index 4d0add4..569fcc0 100644
--- a/core/java/android/tv/TvStreamConfig.aidl
+++ b/media/java/android/media/tv/TvStreamConfig.aidl
@@ -15,6 +15,6 @@
* limitations under the License.
*/
-package android.tv;
+package android.media.tv;
parcelable TvStreamConfig;
\ No newline at end of file
diff --git a/core/java/android/tv/TvStreamConfig.java b/media/java/android/media/tv/TvStreamConfig.java
similarity index 98%
rename from core/java/android/tv/TvStreamConfig.java
rename to media/java/android/media/tv/TvStreamConfig.java
index 03e63b1..7f0c92f 100644
--- a/core/java/android/tv/TvStreamConfig.java
+++ b/media/java/android/media/tv/TvStreamConfig.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.tv;
+package android.media.tv;
import android.os.Parcel;
import android.os.Parcelable;
diff --git a/core/java/android/tv/TvView.java b/media/java/android/media/tv/TvView.java
similarity index 98%
rename from core/java/android/tv/TvView.java
rename to media/java/android/media/tv/TvView.java
index 2d31701..126d739 100644
--- a/core/java/android/tv/TvView.java
+++ b/media/java/android/media/tv/TvView.java
@@ -14,16 +14,16 @@
* limitations under the License.
*/
-package android.tv;
+package android.media.tv;
import android.content.Context;
import android.graphics.Rect;
+import android.media.tv.TvInputManager.Session;
+import android.media.tv.TvInputManager.Session.FinishedInputEventCallback;
+import android.media.tv.TvInputManager.SessionCallback;
import android.os.Bundle;
import android.os.Handler;
import android.text.TextUtils;
-import android.tv.TvInputManager.Session;
-import android.tv.TvInputManager.Session.FinishedInputEventCallback;
-import android.tv.TvInputManager.SessionCallback;
import android.util.AttributeSet;
import android.util.Log;
import android.view.InputEvent;
diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
index 36c1d5c..ec87c6e 100644
--- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
+++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
@@ -88,7 +88,7 @@
private IMediaContainerService.Stub mBinder = new IMediaContainerService.Stub() {
/**
* Creates a new container and copies resource there.
- * @param paackageURI the uri of resource to be copied. Can be either
+ * @param packageURI the uri of resource to be copied. Can be either
* a content uri or a file uri
* @param cid the id of the secure container that should
* be used for creating a secure container into which the resource
@@ -101,13 +101,13 @@
*/
public String copyResourceToContainer(final Uri packageURI, final String cid,
final String key, final String resFileName, final String publicResFileName,
- boolean isExternal, boolean isForwardLocked) {
+ boolean isExternal, boolean isForwardLocked, String abiOverride) {
if (packageURI == null || cid == null) {
return null;
}
return copyResourceInner(packageURI, cid, key, resFileName, publicResFileName,
- isExternal, isForwardLocked);
+ isExternal, isForwardLocked, abiOverride);
}
/**
@@ -153,13 +153,12 @@
/**
* Determine the recommended install location for package
* specified by file uri location.
- * @param fileUri the uri of resource to be copied. Should be a
- * file uri
+ *
* @return Returns PackageInfoLite object containing
* the package info and recommended app location.
*/
public PackageInfoLite getMinimalPackageInfo(final String packagePath, int flags,
- long threshold) {
+ long threshold, String abiOverride) {
PackageInfoLite ret = new PackageInfoLite();
if (packagePath == null) {
@@ -191,7 +190,7 @@
ret.verifiers = pkg.verifiers;
ret.recommendedInstallLocation = recommendAppInstallLocation(pkg.installLocation,
- packagePath, flags, threshold);
+ packagePath, flags, threshold, abiOverride);
return ret;
}
@@ -208,11 +207,11 @@
}
@Override
- public boolean checkExternalFreeStorage(Uri packageUri, boolean isForwardLocked)
- throws RemoteException {
+ public boolean checkExternalFreeStorage(Uri packageUri, boolean isForwardLocked,
+ String abiOverride) throws RemoteException {
final File apkFile = new File(packageUri.getPath());
try {
- return isUnderExternalThreshold(apkFile, isForwardLocked);
+ return isUnderExternalThreshold(apkFile, isForwardLocked, abiOverride);
} catch (IOException e) {
return true;
}
@@ -265,11 +264,11 @@
}
@Override
- public long calculateInstalledSize(String packagePath, boolean isForwardLocked)
- throws RemoteException {
+ public long calculateInstalledSize(String packagePath, boolean isForwardLocked,
+ String abiOverride) throws RemoteException {
final File packageFile = new File(packagePath);
try {
- return calculateContainerSize(packageFile, isForwardLocked) * 1024 * 1024;
+ return calculateContainerSize(packageFile, isForwardLocked, abiOverride) * 1024 * 1024;
} catch (IOException e) {
/*
* Okay, something failed, so let's just estimate it to be 2x
@@ -328,7 +327,8 @@
}
private String copyResourceInner(Uri packageURI, String newCid, String key, String resFileName,
- String publicResFileName, boolean isExternal, boolean isForwardLocked) {
+ String publicResFileName, boolean isExternal, boolean isForwardLocked,
+ String abiOverride) {
if (isExternal) {
// Make sure the sdcard is mounted.
@@ -343,7 +343,22 @@
String codePath = packageURI.getPath();
File codeFile = new File(codePath);
NativeLibraryHelper.ApkHandle handle = new NativeLibraryHelper.ApkHandle(codePath);
- final int abi = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_ABIS);
+ String[] abiList = Build.SUPPORTED_ABIS;
+ if (abiOverride != null) {
+ abiList = new String[] { abiOverride };
+ } else {
+ try {
+ if (Build.SUPPORTED_64_BIT_ABIS.length > 0 &&
+ NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
+ abiList = Build.SUPPORTED_32_BIT_ABIS;
+ }
+ } catch (IOException ioe) {
+ Slog.w(TAG, "Problem determining ABI for: " + codeFile.getPath());
+ return null;
+ }
+ }
+
+ final int abi = NativeLibraryHelper.findSupportedAbi(handle, abiList);
// Calculate size of container needed to hold base APK.
final int sizeMb;
@@ -414,7 +429,7 @@
int ret = PackageManager.INSTALL_SUCCEEDED;
if (abi >= 0) {
ret = NativeLibraryHelper.copyNativeBinariesIfNeededLI(handle,
- sharedLibraryDir, Build.SUPPORTED_ABIS[abi]);
+ sharedLibraryDir, abiList[abi]);
} else if (abi != PackageManager.NO_NATIVE_LIBRARIES) {
ret = abi;
}
@@ -672,7 +687,7 @@
private static final int PREFER_EXTERNAL = 2;
private int recommendAppInstallLocation(int installLocation, String archiveFilePath, int flags,
- long threshold) {
+ long threshold, String abiOverride) {
int prefer;
boolean checkBoth = false;
@@ -741,7 +756,7 @@
boolean fitsOnSd = false;
if (!emulated && (checkBoth || prefer == PREFER_EXTERNAL)) {
try {
- fitsOnSd = isUnderExternalThreshold(apkFile, isForwardLocked);
+ fitsOnSd = isUnderExternalThreshold(apkFile, isForwardLocked, abiOverride);
} catch (IOException e) {
return PackageHelper.RECOMMEND_FAILED_INVALID_URI;
}
@@ -812,13 +827,13 @@
* @return true if file fits
* @throws IOException when file does not exist
*/
- private boolean isUnderExternalThreshold(File apkFile, boolean isForwardLocked)
+ private boolean isUnderExternalThreshold(File apkFile, boolean isForwardLocked, String abiOverride)
throws IOException {
if (Environment.isExternalStorageEmulated()) {
return false;
}
- final int sizeMb = calculateContainerSize(apkFile, isForwardLocked);
+ final int sizeMb = calculateContainerSize(apkFile, isForwardLocked, abiOverride);
final int availSdMb;
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
@@ -832,9 +847,11 @@
return availSdMb > sizeMb;
}
- private int calculateContainerSize(File apkFile, boolean forwardLocked) throws IOException {
+ private int calculateContainerSize(File apkFile, boolean forwardLocked,
+ String abiOverride) throws IOException {
NativeLibraryHelper.ApkHandle handle = new NativeLibraryHelper.ApkHandle(apkFile);
- final int abi = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_ABIS);
+ final int abi = NativeLibraryHelper.findSupportedAbi(handle,
+ (abiOverride != null) ? new String[] { abiOverride } : Build.SUPPORTED_ABIS);
try {
return calculateContainerSize(handle, apkFile, abi, forwardLocked);
diff --git a/packages/Keyguard/Android.mk b/packages/Keyguard/Android.mk
index 1be44f9..96ed2e7 100644
--- a/packages/Keyguard/Android.mk
+++ b/packages/Keyguard/Android.mk
@@ -16,8 +16,7 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-subdir-Iaidl-files) \
- $(call all-proto-files-under,src)
+LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-subdir-Iaidl-files)
LOCAL_MODULE := Keyguard
@@ -27,9 +26,6 @@
LOCAL_PROGUARD_FLAG_FILES := proguard.flags
-LOCAL_PROTOC_OPTIMIZE_TYPE := nano
-LOCAL_PROTO_JAVA_OUTPUT_PARAMS := optional_field_style=accessors
-
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/packages/Keyguard/src/com/android/keyguard/analytics/KeyguardAnalytics.java b/packages/Keyguard/src/com/android/keyguard/analytics/KeyguardAnalytics.java
deleted file mode 100644
index 20af2f1..0000000
--- a/packages/Keyguard/src/com/android/keyguard/analytics/KeyguardAnalytics.java
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.keyguard.analytics;
-
-import com.google.protobuf.nano.CodedOutputByteBufferNano;
-import com.google.protobuf.nano.MessageNano;
-
-import android.content.Context;
-import android.hardware.Sensor;
-import android.hardware.SensorEvent;
-import android.hardware.SensorEventListener;
-import android.hardware.SensorManager;
-import android.os.AsyncTask;
-import android.util.Log;
-import android.view.MotionEvent;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * Tracks sessions, touch and sensor events in Keyguard.
- *
- * A session starts when the user is presented with the Keyguard and ends when the Keyguard is no
- * longer visible to the user.
- */
-public class KeyguardAnalytics implements SensorEventListener {
-
- private static final boolean DEBUG = false;
- private static final String TAG = "KeyguardAnalytics";
- private static final long TIMEOUT_MILLIS = 11000; // 11 seconds.
-
- private static final int[] SENSORS = new int[] {
- Sensor.TYPE_ACCELEROMETER,
- Sensor.TYPE_GYROSCOPE,
- Sensor.TYPE_PROXIMITY,
- Sensor.TYPE_LIGHT,
- Sensor.TYPE_ROTATION_VECTOR,
- };
-
- private Session mCurrentSession = null;
- // Err on the side of caution, so logging is not started after a crash even tough the screen
- // is off.
- private boolean mScreenOn = false;
- private boolean mHidden = false;
-
- private final SensorManager mSensorManager;
- private final SessionTypeAdapter mSessionTypeAdapter;
- private final File mAnalyticsFile;
-
- public KeyguardAnalytics(Context context, SessionTypeAdapter sessionTypeAdapter,
- File analyticsFile) {
- mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
- mSessionTypeAdapter = sessionTypeAdapter;
- mAnalyticsFile = analyticsFile;
- }
-
- public Callback getCallback() {
- return mCallback;
- }
-
- public interface Callback {
- public void onShow();
- public void onHide();
- public void onScreenOn();
- public void onScreenOff();
- public boolean onTouchEvent(MotionEvent ev, int width, int height);
- public void onSetOccluded(boolean hidden);
- }
-
- public interface SessionTypeAdapter {
- public int getSessionType();
- }
-
- private void sessionEntrypoint() {
- if (mCurrentSession == null && mScreenOn && !mHidden) {
- onSessionStart();
- }
- }
-
- private void sessionExitpoint(int result) {
- if (mCurrentSession != null) {
- onSessionEnd(result);
- }
- }
-
- private void onSessionStart() {
- int type = mSessionTypeAdapter.getSessionType();
- mCurrentSession = new Session(System.currentTimeMillis(), System.nanoTime(), type);
- if (type == Session.TYPE_KEYGUARD_SECURE) {
- mCurrentSession.setRedactTouchEvents();
- }
- for (int sensorType : SENSORS) {
- Sensor s = mSensorManager.getDefaultSensor(sensorType);
- if (s != null) {
- mSensorManager.registerListener(this, s, SensorManager.SENSOR_DELAY_GAME);
- }
- }
- if (DEBUG) {
- Log.d(TAG, "onSessionStart()");
- }
- }
-
- private void onSessionEnd(int result) {
- if (DEBUG) {
- Log.d(TAG, String.format("onSessionEnd(success=%d)", result));
- }
- mSensorManager.unregisterListener(this);
-
- Session session = mCurrentSession;
- mCurrentSession = null;
-
- session.end(System.currentTimeMillis(), result);
- queueSession(session);
- }
-
- private void queueSession(final Session currentSession) {
- if (DEBUG) {
- Log.i(TAG, "Saving session.");
- }
- new AsyncTask<Void, Void, Void>() {
- @Override
- protected Void doInBackground(Void... params) {
- try {
- byte[] b = writeDelimitedProto(currentSession.toProto());
- OutputStream os = new FileOutputStream(mAnalyticsFile, true /* append */);
- if (DEBUG) {
- Log.d(TAG, String.format("Serialized size: %d kB.", b.length / 1024));
- }
- try {
- os.write(b);
- os.flush();
- } finally {
- try {
- os.close();
- } catch (IOException e) {
- Log.e(TAG, "Exception while closing file", e);
- }
- }
- } catch (IOException e) {
- Log.e(TAG, "Exception while writing file", e);
- }
- return null;
- }
-
- private byte[] writeDelimitedProto(MessageNano proto)
- throws IOException {
- byte[] result = new byte[CodedOutputByteBufferNano.computeMessageSizeNoTag(proto)];
- CodedOutputByteBufferNano ob = CodedOutputByteBufferNano.newInstance(result);
- ob.writeMessageNoTag(proto);
- ob.checkNoSpaceLeft();
- return result;
- }
- }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
- }
-
- @Override
- public synchronized void onSensorChanged(SensorEvent event) {
- if (false) {
- Log.v(TAG, String.format(
- "onSensorChanged(name=%s, values[0]=%f)",
- event.sensor.getName(), event.values[0]));
- }
- if (mCurrentSession != null) {
- mCurrentSession.addSensorEvent(event, System.nanoTime());
- enforceTimeout();
- }
- }
-
- private void enforceTimeout() {
- if (System.currentTimeMillis() - mCurrentSession.getStartTimestampMillis()
- > TIMEOUT_MILLIS) {
- onSessionEnd(Session.RESULT_UNKNOWN);
- if (DEBUG) {
- Log.i(TAG, "Analytics timed out.");
- }
- }
- }
-
- @Override
- public void onAccuracyChanged(Sensor sensor, int accuracy) {
- }
-
- private final Callback mCallback = new Callback() {
- @Override
- public void onShow() {
- if (DEBUG) {
- Log.d(TAG, "onShow()");
- }
- synchronized (KeyguardAnalytics.this) {
- sessionEntrypoint();
- }
- }
-
- @Override
- public void onHide() {
- if (DEBUG) {
- Log.d(TAG, "onHide()");
- }
- synchronized (KeyguardAnalytics.this) {
- sessionExitpoint(Session.RESULT_SUCCESS);
- }
- }
-
- @Override
- public void onScreenOn() {
- if (DEBUG) {
- Log.d(TAG, "onScreenOn()");
- }
- synchronized (KeyguardAnalytics.this) {
- mScreenOn = true;
- sessionEntrypoint();
- }
- }
-
- @Override
- public void onScreenOff() {
- if (DEBUG) {
- Log.d(TAG, "onScreenOff()");
- }
- synchronized (KeyguardAnalytics.this) {
- mScreenOn = false;
- sessionExitpoint(Session.RESULT_FAILURE);
- }
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent ev, int width, int height) {
- if (DEBUG) {
- Log.v(TAG, "onTouchEvent(ev.action="
- + MotionEvent.actionToString(ev.getAction()) + ")");
- }
- synchronized (KeyguardAnalytics.this) {
- if (mCurrentSession != null) {
- mCurrentSession.addMotionEvent(ev);
- mCurrentSession.setTouchArea(width, height);
- enforceTimeout();
- }
- }
- return true;
- }
-
- @Override
- public void onSetOccluded(boolean hidden) {
- synchronized (KeyguardAnalytics.this) {
- if (hidden != mHidden) {
- if (DEBUG) {
- Log.d(TAG, "onSetOccluded(" + hidden + ")");
- }
- mHidden = hidden;
- if (hidden) {
- // Could have gone to camera on purpose / by falsing or an app could have
- // launched on top of the lockscreen.
- sessionExitpoint(Session.RESULT_UNKNOWN);
- } else {
- sessionEntrypoint();
- }
- }
- }
- }
- };
-
-}
diff --git a/packages/Keyguard/src/com/android/keyguard/analytics/PointerTracker.java b/packages/Keyguard/src/com/android/keyguard/analytics/PointerTracker.java
deleted file mode 100644
index e68f751..0000000
--- a/packages/Keyguard/src/com/android/keyguard/analytics/PointerTracker.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.keyguard.analytics;
-
-import android.graphics.RectF;
-import android.util.FloatMath;
-import android.util.SparseArray;
-import android.view.MotionEvent;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import static com.android.keyguard.analytics.KeyguardAnalyticsProtos.Session.TouchEvent.BoundingBox;
-
-/**
- * Takes motion events and tracks the length and bounding box of each pointer gesture as well as
- * the bounding box of the whole gesture.
- */
-public class PointerTracker {
- private SparseArray<Pointer> mPointerInfoMap = new SparseArray<Pointer>();
- private RectF mTotalBoundingBox = new RectF();
-
- public void addMotionEvent(MotionEvent ev) {
- if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
- float x = ev.getX();
- float y = ev.getY();
- mTotalBoundingBox.set(x, y, x, y);
- }
- for (int i = 0; i < ev.getPointerCount(); i++) {
- int id = ev.getPointerId(i);
- Pointer pointer = getPointer(id);
- float x = ev.getX(i);
- float y = ev.getY(i);
- boolean down = ev.getActionMasked() == MotionEvent.ACTION_DOWN
- || (ev.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN
- && ev.getActionIndex() == i);
- pointer.addPoint(x, y, down);
- mTotalBoundingBox.union(x, y);
- }
- }
-
- public float getPointerLength(int id) {
- return getPointer(id).length;
- }
-
- public BoundingBox getBoundingBox() {
- return boundingBoxFromRect(mTotalBoundingBox);
- }
-
- public BoundingBox getPointerBoundingBox(int id) {
- return boundingBoxFromRect(getPointer(id).boundingBox);
- }
-
- private BoundingBox boundingBoxFromRect(RectF f) {
- BoundingBox bb = new BoundingBox();
- bb.setHeight(f.height());
- bb.setWidth(f.width());
- return bb;
- }
-
- private Pointer getPointer(int id) {
- Pointer p = mPointerInfoMap.get(id);
- if (p == null) {
- p = new Pointer();
- mPointerInfoMap.put(id, p);
- }
- return p;
- }
-
- private static class Pointer {
- public float length;
- public final RectF boundingBox = new RectF();
-
- private float mLastX;
- private float mLastY;
-
- public void addPoint(float x, float y, boolean down) {
- float deltaX;
- float deltaY;
- if (down) {
- boundingBox.set(x, y, x, y);
- length = 0f;
- deltaX = 0;
- deltaY = 0;
- } else {
- deltaX = x - mLastX;
- deltaY = y - mLastY;
- }
- mLastX = x;
- mLastY = y;
- length += FloatMath.sqrt(deltaX * deltaX + deltaY * deltaY);
- boundingBox.union(x, y);
- }
- }
-}
diff --git a/packages/Keyguard/src/com/android/keyguard/analytics/Session.java b/packages/Keyguard/src/com/android/keyguard/analytics/Session.java
deleted file mode 100644
index 05f9165..0000000
--- a/packages/Keyguard/src/com/android/keyguard/analytics/Session.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.keyguard.analytics;
-
-import android.os.Build;
-import android.util.Slog;
-import android.view.MotionEvent;
-
-import java.util.ArrayList;
-
-import static com.android.keyguard.analytics.KeyguardAnalyticsProtos.Session.SensorEvent;
-import static com.android.keyguard.analytics.KeyguardAnalyticsProtos.Session.TouchEvent;
-
-/**
- * Records data about one keyguard session.
- *
- * The recorded data contains start and end of the session, whether it unlocked the device
- * successfully, sensor data and touch data.
- *
- * If the keyguard is secure, the recorded touch data will correlate or contain the user pattern or
- * PIN. If this is not desired, the touch coordinates can be redacted before serialization.
- */
-public class Session {
-
- private static final String TAG = "KeyguardAnalytics";
- private static final boolean DEBUG = false;
-
- /**
- * The user has failed to unlock the device in this session.
- */
- public static final int RESULT_FAILURE = KeyguardAnalyticsProtos.Session.FAILURE;
- /**
- * The user has succeeded in unlocking the device in this session.
- */
- public static final int RESULT_SUCCESS = KeyguardAnalyticsProtos.Session.SUCCESS;
-
- /**
- * It is unknown how the session with the keyguard ended.
- */
- public static final int RESULT_UNKNOWN = KeyguardAnalyticsProtos.Session.UNKNOWN;
-
- /**
- * This session took place on an insecure keyguard.
- */
- public static final int TYPE_KEYGUARD_INSECURE
- = KeyguardAnalyticsProtos.Session.KEYGUARD_INSECURE;
-
- /**
- * This session took place on an secure keyguard.
- */
- public static final int TYPE_KEYGUARD_SECURE
- = KeyguardAnalyticsProtos.Session.KEYGUARD_SECURE;
-
- /**
- * This session took place during a fake wake up of the device.
- */
- public static final int TYPE_RANDOM_WAKEUP = KeyguardAnalyticsProtos.Session.RANDOM_WAKEUP;
-
-
- private final PointerTracker mPointerTracker = new PointerTracker();
-
- private final long mStartTimestampMillis;
- private final long mStartSystemTimeNanos;
- private final int mType;
-
- private boolean mRedactTouchEvents;
- private ArrayList<TouchEvent> mMotionEvents = new ArrayList<TouchEvent>(200);
- private ArrayList<SensorEvent> mSensorEvents = new ArrayList<SensorEvent>(600);
- private int mTouchAreaHeight;
- private int mTouchAreaWidth;
-
- private long mEndTimestampMillis;
- private int mResult;
- private boolean mEnded;
-
- public Session(long startTimestampMillis, long startSystemTimeNanos, int type) {
- mStartTimestampMillis = startTimestampMillis;
- mStartSystemTimeNanos = startSystemTimeNanos;
- mType = type;
- }
-
- public void end(long endTimestampMillis, int result) {
- mEnded = true;
- mEndTimestampMillis = endTimestampMillis;
- mResult = result;
- }
-
- public void addMotionEvent(MotionEvent motionEvent) {
- if (mEnded) {
- return;
- }
- mPointerTracker.addMotionEvent(motionEvent);
- mMotionEvents.add(protoFromMotionEvent(motionEvent));
- }
-
- public void addSensorEvent(android.hardware.SensorEvent eventOrig, long systemTimeNanos) {
- if (mEnded) {
- return;
- }
- SensorEvent event = protoFromSensorEvent(eventOrig, systemTimeNanos);
- mSensorEvents.add(event);
- if (DEBUG) {
- Slog.v(TAG, String.format("addSensorEvent(name=%s, values[0]=%f",
- event.getType(), event.values[0]));
- }
- }
-
- @Override
- public String toString() {
- final StringBuilder sb = new StringBuilder("Session{");
- sb.append("mType=").append(mType);
- sb.append(", mStartTimestampMillis=").append(mStartTimestampMillis);
- sb.append(", mStartSystemTimeNanos=").append(mStartSystemTimeNanos);
- sb.append(", mEndTimestampMillis=").append(mEndTimestampMillis);
- sb.append(", mResult=").append(mResult);
- sb.append(", mRedactTouchEvents=").append(mRedactTouchEvents);
- sb.append(", mTouchAreaHeight=").append(mTouchAreaHeight);
- sb.append(", mTouchAreaWidth=").append(mTouchAreaWidth);
- sb.append(", mMotionEvents=[size=").append(mMotionEvents.size()).append("]");
- sb.append(", mSensorEvents=[size=").append(mSensorEvents.size()).append("]");
- sb.append('}');
- return sb.toString();
- }
-
- public KeyguardAnalyticsProtos.Session toProto() {
- KeyguardAnalyticsProtos.Session proto = new KeyguardAnalyticsProtos.Session();
- proto.setStartTimestampMillis(mStartTimestampMillis);
- proto.setDurationMillis(mEndTimestampMillis - mStartTimestampMillis);
- proto.setBuild(Build.FINGERPRINT);
- proto.setResult(mResult);
- proto.sensorEvents = mSensorEvents.toArray(proto.sensorEvents);
- proto.touchEvents = mMotionEvents.toArray(proto.touchEvents);
- proto.setTouchAreaWidth(mTouchAreaWidth);
- proto.setTouchAreaHeight(mTouchAreaHeight);
- proto.setType(mType);
- if (mRedactTouchEvents) {
- redactTouchEvents(proto.touchEvents);
- }
- return proto;
- }
-
- private void redactTouchEvents(TouchEvent[] touchEvents) {
- for (int i = 0; i < touchEvents.length; i++) {
- TouchEvent t = touchEvents[i];
- for (int j = 0; j < t.pointers.length; j++) {
- TouchEvent.Pointer p = t.pointers[j];
- p.clearX();
- p.clearY();
- }
- t.setRedacted(true);
- }
- }
-
- private SensorEvent protoFromSensorEvent(android.hardware.SensorEvent ev, long sysTimeNanos) {
- SensorEvent proto = new SensorEvent();
- proto.setType(ev.sensor.getType());
- proto.setTimeOffsetNanos(sysTimeNanos - mStartSystemTimeNanos);
- proto.setTimestamp(ev.timestamp);
- proto.values = ev.values.clone();
- return proto;
- }
-
- private TouchEvent protoFromMotionEvent(MotionEvent ev) {
- int count = ev.getPointerCount();
- TouchEvent proto = new TouchEvent();
- proto.setTimeOffsetNanos(ev.getEventTimeNano() - mStartSystemTimeNanos);
- proto.setAction(ev.getActionMasked());
- proto.setActionIndex(ev.getActionIndex());
- proto.pointers = new TouchEvent.Pointer[count];
- for (int i = 0; i < count; i++) {
- TouchEvent.Pointer p = new TouchEvent.Pointer();
- p.setX(ev.getX(i));
- p.setY(ev.getY(i));
- p.setSize(ev.getSize(i));
- p.setPressure(ev.getPressure(i));
- p.setId(ev.getPointerId(i));
- proto.pointers[i] = p;
- if ((ev.getActionMasked() == MotionEvent.ACTION_POINTER_UP && ev.getActionIndex() == i)
- || ev.getActionMasked() == MotionEvent.ACTION_UP) {
- p.boundingBox = mPointerTracker.getPointerBoundingBox(p.getId());
- p.setLength(mPointerTracker.getPointerLength(p.getId()));
- }
- }
- if (ev.getActionMasked() == MotionEvent.ACTION_UP) {
- proto.boundingBox = mPointerTracker.getBoundingBox();
- }
- return proto;
- }
-
- /**
- * Discards the x / y coordinates of the touch events on serialization. Retained are the
- * size of the individual and overall bounding boxes and the length of each pointer's gesture.
- */
- public void setRedactTouchEvents() {
- mRedactTouchEvents = true;
- }
-
- public void setTouchArea(int width, int height) {
- mTouchAreaWidth = width;
- mTouchAreaHeight = height;
- }
-
- public long getStartTimestampMillis() {
- return mStartTimestampMillis;
- }
-}
diff --git a/packages/Keyguard/src/com/android/keyguard/analytics/keyguard_analytics.proto b/packages/Keyguard/src/com/android/keyguard/analytics/keyguard_analytics.proto
deleted file mode 100644
index 68b1590..0000000
--- a/packages/Keyguard/src/com/android/keyguard/analytics/keyguard_analytics.proto
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-syntax = "proto2";
-
-package keyguard;
-
-option java_package = "com.android.keyguard.analytics";
-option java_outer_classname = "KeyguardAnalyticsProtos";
-
-message Session {
- message TouchEvent {
- message BoundingBox {
- optional float width = 1;
- optional float height = 2;
- }
-
- enum Action {
- // Keep in sync with MotionEvent.
- DOWN = 0;
- UP = 1;
- MOVE = 2;
- CANCEL = 3;
- OUTSIDE = 4;
- POINTER_DOWN = 5;
- POINTER_UP = 6;
- }
-
- message Pointer {
- optional float x = 1;
- optional float y = 2;
- optional float size = 3;
- optional float pressure = 4;
- optional int32 id = 5;
- optional float length = 6;
- // Bounding box of the pointer. Only set on UP or POINTER_UP event of this pointer.
- optional BoundingBox boundingBox = 7;
- }
-
- optional uint64 timeOffsetNanos = 1;
- optional Action action = 2;
- optional int32 actionIndex = 3;
- repeated Pointer pointers = 4;
- /* If true, the the x / y coordinates of the touch events were redacted. Retained are the
- size of the individual and overall bounding boxes and the length of each pointer's
- gesture. */
- optional bool redacted = 5;
- // Bounding box of the whole gesture. Only set on UP event.
- optional BoundingBox boundingBox = 6;
- }
-
- message SensorEvent {
- enum Type {
- ACCELEROMETER = 1;
- GYROSCOPE = 4;
- LIGHT = 5;
- PROXIMITY = 8;
- ROTATION_VECTOR = 11;
- }
-
- optional Type type = 1;
- optional uint64 timeOffsetNanos = 2;
- repeated float values = 3;
- optional uint64 timestamp = 4;
- }
-
- enum Result {
- FAILURE = 0;
- SUCCESS = 1;
- UNKNOWN = 2;
- }
-
- enum Type {
- KEYGUARD_INSECURE = 0;
- KEYGUARD_SECURE = 1;
- RANDOM_WAKEUP = 2;
- }
-
- optional uint64 startTimestampMillis = 1;
- optional uint64 durationMillis = 2;
- optional string build = 3;
- optional Result result = 4;
- repeated TouchEvent touchEvents = 5;
- repeated SensorEvent sensorEvents = 6;
-
- optional int32 touchAreaWidth = 9;
- optional int32 touchAreaHeight = 10;
- optional Type type = 11;
-}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index f7b4994..4837a53 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -59,8 +59,6 @@
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.keyguard.MultiUserAvatarCache;
import com.android.keyguard.ViewMediatorCallback;
-import com.android.keyguard.analytics.KeyguardAnalytics;
-import com.android.keyguard.analytics.Session;
import com.android.systemui.SystemUI;
import com.android.systemui.statusbar.phone.PhoneStatusBar;
import com.android.systemui.statusbar.phone.ScrimController;
@@ -70,7 +68,6 @@
import java.io.File;
import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
-import static com.android.keyguard.analytics.KeyguardAnalytics.SessionTypeAdapter;
/**
@@ -117,7 +114,6 @@
public class KeyguardViewMediator extends SystemUI {
private static final int KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT = 30000;
final static boolean DEBUG = false;
- private static final boolean ENABLE_ANALYTICS = Build.IS_DEBUGGABLE;
private final static boolean DBG_WAKE = false;
private final static String TAG = "KeyguardViewMediator";
@@ -199,8 +195,6 @@
private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
- private KeyguardAnalytics mKeyguardAnalytics;
-
// these are protected by synchronized (this)
/**
@@ -469,22 +463,6 @@
mViewMediatorCallback, mLockPatternUtils);
final ContentResolver cr = mContext.getContentResolver();
- if (ENABLE_ANALYTICS && !LockPatternUtils.isSafeModeEnabled() &&
- Settings.Secure.getInt(cr, KEYGUARD_ANALYTICS_SETTING, 0) == 1) {
- mKeyguardAnalytics = new KeyguardAnalytics(mContext, new SessionTypeAdapter() {
-
- @Override
- public int getSessionType() {
- return mLockPatternUtils.isSecure() && !mUpdateMonitor.getUserHasTrust(
- mLockPatternUtils.getCurrentUser())
- ? Session.TYPE_KEYGUARD_SECURE
- : Session.TYPE_KEYGUARD_INSECURE;
- }
- }, new File(mContext.getCacheDir(), "keyguard_analytics.bin"));
- } else {
- mKeyguardAnalytics = null;
- }
-
mScreenOn = mPM.isScreenOn();
mLockSounds = new SoundPool(1, AudioManager.STREAM_SYSTEM, 0);
@@ -585,9 +563,6 @@
} else {
doKeyguardLocked(null);
}
- if (ENABLE_ANALYTICS && mKeyguardAnalytics != null) {
- mKeyguardAnalytics.getCallback().onScreenOff();
- }
}
KeyguardUpdateMonitor.getInstance(mContext).dispatchScreenTurndOff(why);
}
@@ -830,9 +805,6 @@
updateActivityLockScreenState();
adjustStatusBarLocked();
}
- if (ENABLE_ANALYTICS && mKeyguardAnalytics != null) {
- mKeyguardAnalytics.getCallback().onSetOccluded(isOccluded);
- }
}
}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 22ecd33..b2b4217 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -258,17 +258,6 @@
*/
private NetworkStateTracker mNetTrackers[];
- /**
- * Holds references to all NetworkAgentInfos claiming to support the legacy
- * NetworkType. We used to have a static set of of NetworkStateTrackers
- * for each network type. This is the new model.
- * Supports synchronous inspection of state.
- * These are built out at startup such that an unsupported network
- * doesn't get an ArrayList instance, making this a tristate:
- * unsupported, supported but not active and active.
- */
- private ArrayList<NetworkAgentInfo> mNetworkAgentInfoForType[];
-
/* Handles captive portal check on a network */
private CaptivePortalTracker mCaptivePortalTracker;
@@ -516,6 +505,118 @@
private static final int UID_UNUSED = -1;
+ /**
+ * Implements support for the legacy "one network per network type" model.
+ *
+ * We used to have a static array of NetworkStateTrackers, one for each
+ * network type, but that doesn't work any more now that we can have,
+ * for example, more that one wifi network. This class stores all the
+ * NetworkAgentInfo objects that support a given type, but the legacy
+ * API will only see the first one.
+ *
+ * It serves two main purposes:
+ *
+ * 1. Provide information about "the network for a given type" (since this
+ * API only supports one).
+ * 2. Send legacy connectivity change broadcasts. Broadcasts are sent if
+ * the first network for a given type changes, or if the default network
+ * changes.
+ */
+ private class LegacyTypeTracker {
+ /**
+ * Array of lists, one per legacy network type (e.g., TYPE_MOBILE_MMS).
+ * Each list holds references to all NetworkAgentInfos that are used to
+ * satisfy requests for that network type.
+ *
+ * This array is built out at startup such that an unsupported network
+ * doesn't get an ArrayList instance, making this a tristate:
+ * unsupported, supported but not active and active.
+ *
+ * The actual lists are populated when we scan the network types that
+ * are supported on this device.
+ */
+ private ArrayList<NetworkAgentInfo> mTypeLists[];
+
+ public LegacyTypeTracker() {
+ mTypeLists = (ArrayList<NetworkAgentInfo>[])
+ new ArrayList[ConnectivityManager.MAX_NETWORK_TYPE + 1];
+ }
+
+ public void addSupportedType(int type) {
+ if (mTypeLists[type] != null) {
+ throw new IllegalStateException(
+ "legacy list for type " + type + "already initialized");
+ }
+ mTypeLists[type] = new ArrayList<NetworkAgentInfo>();
+ }
+
+ private boolean isDefaultNetwork(NetworkAgentInfo nai) {
+ return mNetworkForRequestId.get(mDefaultRequest.requestId) == nai;
+ }
+
+ public boolean isTypeSupported(int type) {
+ return isNetworkTypeValid(type) && mTypeLists[type] != null;
+ }
+
+ public NetworkAgentInfo getNetworkForType(int type) {
+ if (isTypeSupported(type) && !mTypeLists[type].isEmpty()) {
+ return mTypeLists[type].get(0);
+ } else {
+ return null;
+ }
+ }
+
+ public void add(int type, NetworkAgentInfo nai) {
+ if (!isTypeSupported(type)) {
+ return; // Invalid network type.
+ }
+ if (VDBG) log("Adding agent " + nai + " for legacy network type " + type);
+
+ ArrayList<NetworkAgentInfo> list = mTypeLists[type];
+ if (list.contains(nai)) {
+ loge("Attempting to register duplicate agent for type " + type + ": " + nai);
+ return;
+ }
+
+ if (list.isEmpty() || isDefaultNetwork(nai)) {
+ if (VDBG) log("Sending connected broadcast for type " + type +
+ "isDefaultNetwork=" + isDefaultNetwork(nai));
+ sendLegacyNetworkBroadcast(nai, true, type);
+ }
+ list.add(nai);
+ }
+
+ public void remove(NetworkAgentInfo nai) {
+ if (VDBG) log("Removing agent " + nai);
+ for (int type = 0; type < mTypeLists.length; type++) {
+ ArrayList<NetworkAgentInfo> list = mTypeLists[type];
+ if (list == null || list.isEmpty()) {
+ continue;
+ }
+
+ boolean wasFirstNetwork = false;
+ if (list.get(0).equals(nai)) {
+ // This network was the first in the list. Send broadcast.
+ wasFirstNetwork = true;
+ }
+ list.remove(nai);
+
+ if (wasFirstNetwork || isDefaultNetwork(nai)) {
+ if (VDBG) log("Sending disconnected broadcast for type " + type +
+ "isDefaultNetwork=" + isDefaultNetwork(nai));
+ sendLegacyNetworkBroadcast(nai, false, type);
+ }
+
+ if (!list.isEmpty() && wasFirstNetwork) {
+ if (VDBG) log("Other network available for type " + type +
+ ", sending connected broadcast");
+ sendLegacyNetworkBroadcast(list.get(0), false, type);
+ }
+ }
+ }
+ }
+ private LegacyTypeTracker mLegacyTypeTracker = new LegacyTypeTracker();
+
public ConnectivityService(Context context, INetworkManagementService netd,
INetworkStatsService statsService, INetworkPolicyManager policyManager) {
// Currently, omitting a NetworkFactory will create one internally
@@ -531,7 +632,7 @@
NetworkCapabilities netCap = new NetworkCapabilities();
netCap.addNetworkCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
netCap.addNetworkCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
- mDefaultRequest = new NetworkRequest(netCap, true, nextNetworkRequestId());
+ mDefaultRequest = new NetworkRequest(netCap, TYPE_NONE, nextNetworkRequestId());
NetworkRequestInfo nri = new NetworkRequestInfo(null, mDefaultRequest, new Binder(),
NetworkRequestInfo.REQUEST);
mNetworkRequests.put(mDefaultRequest, nri);
@@ -587,9 +688,6 @@
mNetTransitionWakeLockTimeout = mContext.getResources().getInteger(
com.android.internal.R.integer.config_networkTransitionTimeout);
- mNetworkAgentInfoForType = (ArrayList<NetworkAgentInfo>[])
- new ArrayList[ConnectivityManager.MAX_NETWORK_TYPE + 1];
-
mNetTrackers = new NetworkStateTracker[
ConnectivityManager.MAX_NETWORK_TYPE+1];
mCurrentLinkProperties = new LinkProperties[ConnectivityManager.MAX_NETWORK_TYPE+1];
@@ -644,7 +742,7 @@
"radio " + n.radio + " in network type " + n.type);
continue;
}
- mNetworkAgentInfoForType[n.type] = new ArrayList<NetworkAgentInfo>();
+ mLegacyTypeTracker.addSupportedType(n.type);
mNetConfigs[n.type] = n;
mNetworksDefined++;
@@ -3125,11 +3223,9 @@
} else {
loge("Error connecting NetworkAgent");
NetworkAgentInfo nai = mNetworkAgentInfos.remove(msg.replyTo);
- try {
- mNetworkAgentInfoForType[nai.networkInfo.getType()].remove(nai);
- } catch (NullPointerException e) {}
if (nai != null) {
mNetworkForNetId.remove(nai.network.netId);
+ mLegacyTypeTracker.remove(nai);
}
}
}
@@ -3160,10 +3256,7 @@
nai.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_DISCONNECTED);
mNetworkAgentInfos.remove(msg.replyTo);
updateClat(null, nai.linkProperties, nai);
- try {
- mNetworkAgentInfoForType[nai.networkInfo.getType()].remove(nai);
- } catch (NullPointerException e) {}
-
+ mLegacyTypeTracker.remove(nai);
mNetworkForNetId.remove(nai.network.netId);
// Since we've lost the network, go through all the requests that
// it was satisfying and see if any other factory can satisfy them.
@@ -3173,7 +3266,7 @@
NetworkAgentInfo currentNetwork = mNetworkForRequestId.get(request.requestId);
if (VDBG) {
log(" checking request " + request + ", currentNetwork = " +
- currentNetwork != null ? currentNetwork.name() : "null");
+ (currentNetwork != null ? currentNetwork.name() : "null"));
}
if (currentNetwork != null && currentNetwork.network.netId == nai.network.netId) {
mNetworkForRequestId.remove(request.requestId);
@@ -3223,6 +3316,10 @@
if (bestNetwork != null) {
if (VDBG) log("using " + bestNetwork.name());
bestNetwork.addRequest(nri.request);
+ int legacyType = nri.request.legacyType;
+ if (legacyType != TYPE_NONE) {
+ mLegacyTypeTracker.add(legacyType, bestNetwork);
+ }
notifyNetworkCallback(bestNetwork, nri);
score = bestNetwork.currentScore;
}
@@ -5300,7 +5397,7 @@
@Override
public NetworkRequest requestNetwork(NetworkCapabilities networkCapabilities,
- Messenger messenger, int timeoutSec, IBinder binder, boolean legacy) {
+ Messenger messenger, int timeoutSec, IBinder binder, int legacyType) {
if (networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
== false) {
enforceConnectivityInternalPermission();
@@ -5312,7 +5409,7 @@
throw new IllegalArgumentException("Bad timeout specified");
}
NetworkRequest networkRequest = new NetworkRequest(new NetworkCapabilities(
- networkCapabilities), legacy, nextNetworkRequestId());
+ networkCapabilities), legacyType, nextNetworkRequestId());
if (DBG) log("requestNetwork for " + networkRequest);
NetworkRequestInfo nri = new NetworkRequestInfo(messenger, networkRequest, binder,
NetworkRequestInfo.REQUEST);
@@ -5338,7 +5435,7 @@
enforceAccessPermission();
NetworkRequest networkRequest = new NetworkRequest(new NetworkCapabilities(
- networkCapabilities), false, nextNetworkRequestId());
+ networkCapabilities), TYPE_NONE, nextNetworkRequestId());
if (DBG) log("listenForNetwork for " + networkRequest);
NetworkRequestInfo nri = new NetworkRequestInfo(messenger, networkRequest, binder,
NetworkRequestInfo.LISTEN);
@@ -5420,11 +5517,6 @@
private void handleRegisterNetworkAgent(NetworkAgentInfo na) {
if (VDBG) log("Got NetworkAgent Messenger");
mNetworkAgentInfos.put(na.messenger, na);
- try {
- mNetworkAgentInfoForType[na.networkInfo.getType()].add(na);
- } catch (NullPointerException e) {
- loge("registered NetworkAgent for unsupported type: " + na);
- }
mNetworkForNetId.put(na.network.netId, na);
na.asyncChannel.connect(mContext, mTrackerHandler, na.messenger);
NetworkInfo networkInfo = na.networkInfo;
@@ -5681,6 +5773,10 @@
}
mNetworkForRequestId.put(nri.request.requestId, newNetwork);
newNetwork.addRequest(nri.request);
+ int legacyType = nri.request.legacyType;
+ if (legacyType != TYPE_NONE) {
+ mLegacyTypeTracker.add(legacyType, newNetwork);
+ }
keep = true;
// TODO - this could get expensive if we have alot of requests for this
// network. Think about if there is a way to reduce this. Push
@@ -5694,6 +5790,7 @@
} else {
setDefaultDnsSystemProperties(new ArrayList<InetAddress>());
}
+ mLegacyTypeTracker.add(newNetwork.networkInfo.getType(), newNetwork);
}
}
}
@@ -5828,13 +5925,53 @@
// } else if (nai.networkMonitor.isEvaluating()) {
// notifyType = NetworkCallbacks.callCallbackForRequest(request, nai, notifyType);
// }
- if (nri.request.needsBroadcasts) {
- // TODO
-// sendNetworkBroadcast(nai, notifyType);
- }
callCallbackForRequest(nri, nai, notifyType);
}
+ private void sendLegacyNetworkBroadcast(NetworkAgentInfo nai, boolean connected, int type) {
+ if (connected) {
+ NetworkInfo info = new NetworkInfo(nai.networkInfo);
+ info.setType(type);
+ sendConnectedBroadcastDelayed(info, getConnectivityChangeDelay());
+ } else {
+ NetworkInfo info = new NetworkInfo(nai.networkInfo);
+ info.setType(type);
+ Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION);
+ intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info);
+ intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType());
+ if (info.isFailover()) {
+ intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true);
+ nai.networkInfo.setFailover(false);
+ }
+ if (info.getReason() != null) {
+ intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason());
+ }
+ if (info.getExtraInfo() != null) {
+ intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO, info.getExtraInfo());
+ }
+ NetworkAgentInfo newDefaultAgent = null;
+ if (nai.networkRequests.get(mDefaultRequest.requestId) != null) {
+ newDefaultAgent = mNetworkForRequestId.get(mDefaultRequest.requestId);
+ if (newDefaultAgent != null) {
+ intent.putExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO,
+ newDefaultAgent.networkInfo);
+ } else {
+ intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true);
+ }
+ }
+ intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION,
+ mDefaultInetConditionPublished);
+ final Intent immediateIntent = new Intent(intent);
+ immediateIntent.setAction(CONNECTIVITY_ACTION_IMMEDIATE);
+ sendStickyBroadcast(immediateIntent);
+ sendStickyBroadcastDelayed(intent, getConnectivityChangeDelay());
+ if (newDefaultAgent != null) {
+ sendConnectedBroadcastDelayed(newDefaultAgent.networkInfo,
+ getConnectivityChangeDelay());
+ }
+ }
+ }
+
protected void notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType) {
if (VDBG) log("notifyType " + notifyType + " for " + networkAgent.name());
for (int i = 0; i < networkAgent.networkRequests.size(); i++) {
@@ -5843,76 +5980,33 @@
if (VDBG) log(" sending notification for " + nr);
callCallbackForRequest(nri, networkAgent, notifyType);
}
- if (networkAgent.needsBroadcasts) {
- if (notifyType == ConnectivityManager.CALLBACK_AVAILABLE) {
- sendConnectedBroadcastDelayed(networkAgent.networkInfo,
- getConnectivityChangeDelay());
- } else if (notifyType == ConnectivityManager.CALLBACK_LOST) {
- NetworkInfo info = new NetworkInfo(networkAgent.networkInfo);
- Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION);
- intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info);
- intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType());
- if (info.isFailover()) {
- intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true);
- networkAgent.networkInfo.setFailover(false);
- }
- if (info.getReason() != null) {
- intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason());
- }
- if (info.getExtraInfo() != null) {
- intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO, info.getExtraInfo());
- }
- NetworkAgentInfo newDefaultAgent = null;
- if (networkAgent.networkRequests.get(mDefaultRequest.requestId) != null) {
- newDefaultAgent = mNetworkForRequestId.get(mDefaultRequest.requestId);
- if (newDefaultAgent != null) {
- intent.putExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO,
- newDefaultAgent.networkInfo);
- } else {
- intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true);
- }
- }
- intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION,
- mDefaultInetConditionPublished);
- final Intent immediateIntent = new Intent(intent);
- immediateIntent.setAction(CONNECTIVITY_ACTION_IMMEDIATE);
- sendStickyBroadcast(immediateIntent);
- sendStickyBroadcastDelayed(intent, getConnectivityChangeDelay());
- if (newDefaultAgent != null) {
- sendConnectedBroadcastDelayed(newDefaultAgent.networkInfo,
- getConnectivityChangeDelay());
- }
- }
- }
}
private LinkProperties getLinkPropertiesForTypeInternal(int networkType) {
- ArrayList<NetworkAgentInfo> list = mNetworkAgentInfoForType[networkType];
- if (list == null) return null;
- try {
- return new LinkProperties(list.get(0).linkProperties);
- } catch (IndexOutOfBoundsException e) {
- return new LinkProperties();
- }
+ NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
+ return (nai != null) ?
+ new LinkProperties(nai.linkProperties) :
+ new LinkProperties();
}
private NetworkInfo getNetworkInfoForType(int networkType) {
- ArrayList<NetworkAgentInfo> list = mNetworkAgentInfoForType[networkType];
- if (list == null) return null;
- try {
- return new NetworkInfo(list.get(0).networkInfo);
- } catch (IndexOutOfBoundsException e) {
- return new NetworkInfo(networkType, 0, "Unknown", "");
+ if (!mLegacyTypeTracker.isTypeSupported(networkType))
+ return null;
+
+ NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
+ if (nai != null) {
+ NetworkInfo result = new NetworkInfo(nai.networkInfo);
+ result.setType(networkType);
+ return result;
+ } else {
+ return new NetworkInfo(networkType, 0, "Unknown", "");
}
}
private NetworkCapabilities getNetworkCapabilitiesForType(int networkType) {
- ArrayList<NetworkAgentInfo> list = mNetworkAgentInfoForType[networkType];
- if (list == null) return null;
- try {
- return new NetworkCapabilities(list.get(0).networkCapabilities);
- } catch (IndexOutOfBoundsException e) {
- return new NetworkCapabilities();
- }
+ NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
+ return (nai != null) ?
+ new NetworkCapabilities(nai.networkCapabilities) :
+ new NetworkCapabilities();
}
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 61ba6e0..aede797 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -2978,6 +2978,10 @@
}
}
buf.append("}");
+ if (requiredAbi != null) {
+ buf.append(" abi=");
+ buf.append(requiredAbi);
+ }
Slog.i(TAG, buf.toString());
app.setPid(startResult.pid);
app.usingWrapper = startResult.usingWrapper;
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index e9f9683..b03c247 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -45,18 +45,6 @@
public int currentScore;
public final NetworkMonitor networkMonitor;
- /**
- * Indicates we need to send CONNECTIVITY_ACTION broadcasts for this network.
- * For example the built-in default network request and any requsts coming from
- * the deprecated startUsingNetworkFeature API will have this set. Networks
- * responding to the new requestNetwork API will rely on point to point callbacks.
- *
- * Gets set if any legacy requests get affiliated with this network and
- * stays set for life so we send disconnected bcasts to match the connected,
- * even if the legacy request has moved on.
- */
- public boolean needsBroadcasts = false;
-
// The list of NetworkRequests being satisfied by this Network.
public final SparseArray<NetworkRequest> networkRequests = new SparseArray<NetworkRequest>();
public final ArrayList<NetworkRequest> networkLingered = new ArrayList<NetworkRequest>();
@@ -78,8 +66,6 @@
}
public void addRequest(NetworkRequest networkRequest) {
- if (networkRequest.needsBroadcasts) needsBroadcasts = true;
-
networkRequests.put(networkRequest.requestId, networkRequest);
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecController.java b/services/core/java/com/android/server/hdmi/HdmiCecController.java
index d0b716d..5141d16 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecController.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecController.java
@@ -505,7 +505,7 @@
// Reply <Feature Abort> to initiator (source) for all requests.
HdmiCecMessage cecMessage = HdmiCecMessageBuilder.buildFeatureAbortCommand(
sourceAddress, message.getSource(), message.getOpcode(),
- HdmiCecMessageBuilder.ABORT_REFUSED);
+ HdmiConstants.ABORT_REFUSED);
sendCommand(cecMessage, null);
}
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java
index 9a76734..6c2be34 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java
@@ -26,15 +26,6 @@
* A helper class to build {@link HdmiCecMessage} from various cec commands.
*/
public class HdmiCecMessageBuilder {
- // TODO: move these values to HdmiCec.java once make it internal constant class.
- // CEC's ABORT reason values.
- static final int ABORT_UNRECOGNIZED_MODE = 0;
- static final int ABORT_NOT_IN_CORRECT_MODE = 1;
- static final int ABORT_CANNOT_PROVIDE_SOURCE = 2;
- static final int ABORT_INVALID_OPERAND = 3;
- static final int ABORT_REFUSED = 4;
- static final int ABORT_UNABLE_TO_DETERMINE = 5;
-
private static final int OSD_NAME_MAX_LENGTH = 13;
private HdmiCecMessageBuilder() {}
@@ -290,6 +281,64 @@
}
/**
+ * Build <System Audio Mode Request> command.
+ *
+ * @param src source address of command
+ * @param avr destination address of command, it should be AVR
+ * @param avrPhysicalAddress physical address of AVR
+ * @param enableSystemAudio whether to enable System Audio Mode or not
+ * @return newly created {@link HdmiCecMessage}
+ */
+ static HdmiCecMessage buildSystemAudioModeRequest(int src, int avr, int avrPhysicalAddress,
+ boolean enableSystemAudio) {
+ if (enableSystemAudio) {
+ return buildCommand(src, avr, HdmiCec.MESSAGE_SYSTEM_AUDIO_MODE_REQUEST,
+ physicalAddressToParam(avrPhysicalAddress));
+ } else {
+ return buildCommand(src, avr, HdmiCec.MESSAGE_SYSTEM_AUDIO_MODE_REQUEST);
+ }
+ }
+
+ /**
+ * Build <Give Audio Status> command.
+ *
+ * @param src source address of command
+ * @param dest destination address of command
+ * @return newly created {@link HdmiCecMessage}
+ */
+ static HdmiCecMessage buildGiveAudioStatus(int src, int dest) {
+ return buildCommand(src, dest, HdmiCec.MESSAGE_GIVE_AUDIO_STATUS);
+ }
+
+ /**
+ * Build <User Control Pressed> command.
+ *
+ * @param src source address of command
+ * @param dest destination address of command
+ * @param uiCommand keycode that user pressed
+ * @return newly created {@link HdmiCecMessage}
+ */
+ static HdmiCecMessage buildUserControlPressed(int src, int dest, int uiCommand) {
+ byte[] params = new byte[] {
+ (byte) uiCommand
+ };
+ return buildCommand(src, dest, HdmiCec.MESSAGE_USER_CONTROL_PRESSED, params);
+ }
+
+ /**
+ * Build <User Control Released> command.
+ *
+ * @param src source address of command
+ * @param dest destination address of command
+ * @return newly created {@link HdmiCecMessage}
+ */
+ static HdmiCecMessage buildUserControlReleased(int src, int dest) {
+ return buildCommand(src, dest, HdmiCec.MESSAGE_USER_CONTROL_RELEASED);
+ }
+
+ /***** Please ADD new buildXXX() methods above. ******/
+
+ /**
* Build a {@link HdmiCecMessage} without extra parameter.
*
* @param src source address of command
diff --git a/services/core/java/com/android/server/hdmi/HdmiConstants.java b/services/core/java/com/android/server/hdmi/HdmiConstants.java
new file mode 100644
index 0000000..a83d1ed
--- /dev/null
+++ b/services/core/java/com/android/server/hdmi/HdmiConstants.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.hdmi;
+
+/**
+ * Defines constants related to HDMI-CEC protocol internal implementation.
+ * If a constant will be used in the public api, it should be located in
+ * {@link android.hardware.hdmi.HdmiCec}.
+ */
+final class HdmiConstants {
+
+ // Constants related to operands of HDMI CEC commands.
+ // Refer to CEC Table 29 in HDMI Spec v1.4b.
+ // [Abort Reason]
+ static final int ABORT_UNRECOGNIZED_MODE = 0;
+ static final int ABORT_NOT_IN_CORRECT_MODE = 1;
+ static final int ABORT_CANNOT_PROVIDE_SOURCE = 2;
+ static final int ABORT_INVALID_OPERAND = 3;
+ static final int ABORT_REFUSED = 4;
+ static final int ABORT_UNABLE_TO_DETERMINE = 5;
+
+ // [Audio Status]
+ static final int SYSTEM_AUDIO_STATUS_OFF = 0;
+ static final int SYSTEM_AUDIO_STATUS_ON = 1;
+
+ // Constants related to UI Command Codes.
+ // Refer to CEC Table 30 in HDMI Spec v1.4b.
+ static final int UI_COMMAND_MUTE = 0x43;
+ static final int UI_COMMAND_MUTE_FUNCTION = 0x65;
+ static final int UI_COMMAND_RESTORE_VOLUME_FUNCTION = 0x66;
+
+ private HdmiConstants() { /* cannot be instantiated */ }
+}
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index d775733..0f3fc21 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -118,8 +118,11 @@
// TODO: it may need to hold lock if it's accessed from others.
private boolean mArcStatusEnabled = false;
+ // Whether SystemAudioMode is "On" or not.
+ private boolean mSystemAudioMode;
+
// Handler running on service thread. It's used to run a task in service thread.
- private Handler mHandler = new Handler();
+ private final Handler mHandler = new Handler();
public HdmiControlService(Context context) {
super(context);
@@ -158,6 +161,9 @@
}
publishBinderService(Context.HDMI_CONTROL_SERVICE, new BinderService());
+
+ // TODO: Read the preference for SystemAudioMode and initialize mSystemAudioMode and
+ // start to monitor the preference value and invoke SystemAudioActionFromTv if needed.
}
/**
@@ -211,35 +217,43 @@
* @param action {@link FeatureAction} to remove
*/
void removeAction(final FeatureAction action) {
- runOnServiceThread(new Runnable() {
- @Override
- public void run() {
- mActions.remove(action);
- }
- });
+ assertRunOnServiceThread();
+ mActions.remove(action);
}
// Remove all actions matched with the given Class type.
private <T extends FeatureAction> void removeAction(final Class<T> clazz) {
- runOnServiceThread(new Runnable() {
- @Override
- public void run() {
- Iterator<FeatureAction> iter = mActions.iterator();
- while (iter.hasNext()) {
- FeatureAction action = iter.next();
- if (action.getClass().equals(clazz)) {
- action.clear();
- mActions.remove(action);
- }
- }
+ removeActionExcept(clazz, null);
+ }
+
+ // Remove all actions matched with the given Class type besides |exception|.
+ <T extends FeatureAction> void removeActionExcept(final Class<T> clazz,
+ final FeatureAction exception) {
+ assertRunOnServiceThread();
+ Iterator<FeatureAction> iter = mActions.iterator();
+ while (iter.hasNext()) {
+ FeatureAction action = iter.next();
+ if (action != exception && action.getClass().equals(clazz)) {
+ action.clear();
+ mActions.remove(action);
}
- });
+ }
}
private void runOnServiceThread(Runnable runnable) {
mHandler.post(runnable);
}
+ void runOnServiceThreadAtFrontOfQueue(Runnable runnable) {
+ mHandler.postAtFrontOfQueue(runnable);
+ }
+
+ private void assertRunOnServiceThread() {
+ if (Looper.myLooper() != mHandler.getLooper()) {
+ throw new IllegalStateException("Should run on service thread.");
+ }
+ }
+
/**
* Change ARC status into the given {@code enabled} status.
*
@@ -306,8 +320,12 @@
case HdmiCec.MESSAGE_REPORT_PHYSICAL_ADDRESS:
handleReportPhysicalAddress(message);
return true;
- // TODO: Add remaining system information query such as
- // <Give Device Power Status> and <Request Active Source> handler.
+ case HdmiCec.MESSAGE_SET_SYSTEM_AUDIO_MODE:
+ handleSetSystemAudioMode(message);
+ return true;
+ case HdmiCec.MESSAGE_SYSTEM_AUDIO_MODE_STATUS:
+ handleSystemAudioModeStatus(message);
+ return true;
default:
return dispatchMessageToAction(message);
}
@@ -413,7 +431,7 @@
sendCecCommand(
HdmiCecMessageBuilder.buildFeatureAbortCommand(message.getDestination(),
message.getSource(), HdmiCec.MESSAGE_GET_MENU_LANGUAGE,
- HdmiCecMessageBuilder.ABORT_UNRECOGNIZED_MODE));
+ HdmiConstants.ABORT_UNRECOGNIZED_MODE));
return;
}
@@ -438,6 +456,33 @@
return false;
}
+ private void handleSetSystemAudioMode(HdmiCecMessage message) {
+ if (dispatchMessageToAction(message) || !isMessageForSystemAudio(message)) {
+ return;
+ }
+ SystemAudioActionFromAvr action = new SystemAudioActionFromAvr(this,
+ message.getDestination(), message.getSource(),
+ HdmiUtils.parseCommandParamSystemAudioStatus(message));
+ addAndStartAction(action);
+ }
+
+ private void handleSystemAudioModeStatus(HdmiCecMessage message) {
+ if (!isMessageForSystemAudio(message)) {
+ return;
+ }
+ setSystemAudioMode(HdmiUtils.parseCommandParamSystemAudioStatus(message));
+ }
+
+ private boolean isMessageForSystemAudio(HdmiCecMessage message) {
+ if (message.getSource() != HdmiCec.ADDR_AUDIO_SYSTEM
+ || message.getDestination() != HdmiCec.ADDR_TV
+ || getAvrDeviceInfo() == null) {
+ Slog.w(TAG, "Skip abnormal CecMessage: " + message);
+ return false;
+ }
+ return true;
+ }
+
// Record class that monitors the event of the caller of being killed. Used to clean up
// the listener list and record list accordingly.
private final class HotplugEventListenerRecord implements IBinder.DeathRecipient {
@@ -627,4 +672,32 @@
Slog.e(TAG, "Invoking callback failed:" + e);
}
}
+
+ HdmiCecDeviceInfo getAvrDeviceInfo() {
+ return mCecController.getDeviceInfo(HdmiCec.ADDR_AUDIO_SYSTEM);
+ }
+
+ void setSystemAudioMode(boolean newMode) {
+ assertRunOnServiceThread();
+ if (newMode != mSystemAudioMode) {
+ // TODO: Need to set the preference for SystemAudioMode.
+ // TODO: Need to handle the notification of changing the mode and
+ // to identify the notification should be handled in the service or TvSettings.
+ mSystemAudioMode = newMode;
+ }
+ }
+
+ boolean getSystemAudioMode() {
+ assertRunOnServiceThread();
+ return mSystemAudioMode;
+ }
+
+ void setAudioStatus(boolean mute, int volume) {
+ // TODO: Hook up with AudioManager.
+ }
+
+ boolean isInPresetInstallationMode() {
+ // TODO: Implement this.
+ return false;
+ }
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiUtils.java b/services/core/java/com/android/server/hdmi/HdmiUtils.java
new file mode 100644
index 0000000..ef128ed1
--- /dev/null
+++ b/services/core/java/com/android/server/hdmi/HdmiUtils.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.hdmi;
+
+import android.hardware.hdmi.HdmiCec;
+import android.hardware.hdmi.HdmiCecMessage;
+import android.util.Slog;
+
+/**
+ * Various utilities to handle HDMI CEC messages.
+ */
+final class HdmiUtils {
+
+ private HdmiUtils() { /* cannot be instantiated */ }
+
+ /**
+ * Verify if the given address is for the given device type. If not it will throw
+ * {@link IllegalArgumentException}.
+ *
+ * @param logicalAddress the logical address to verify
+ * @param deviceType the device type to check
+ * @throw IllegalArgumentException
+ */
+ static void verifyAddressType(int logicalAddress, int deviceType) {
+ int actualDeviceType = HdmiCec.getTypeFromAddress(logicalAddress);
+ if (actualDeviceType != deviceType) {
+ throw new IllegalArgumentException("Device type missmatch:[Expected:" + deviceType
+ + ", Actual:" + actualDeviceType);
+ }
+ }
+
+ /**
+ * Check if the given CEC message come from the given address.
+ *
+ * @param cmd the CEC message to check
+ * @param expectedAddress the expected source address of the given message
+ * @param tag the tag of caller module (for log message)
+ * @return true if the CEC message comes from the given address
+ */
+ static boolean checkCommandSource(HdmiCecMessage cmd, int expectedAddress, String tag) {
+ int src = cmd.getSource();
+ if (src != expectedAddress) {
+ Slog.w(tag, "Invalid source [Expected:" + expectedAddress + ", Actual:" + src + "]");
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Parse the parameter block of CEC message as [System Audio Status].
+ *
+ * @param cmd the CEC message to parse
+ * @return true if the given parameter has [ON] value
+ */
+ static boolean parseCommandParamSystemAudioStatus(HdmiCecMessage cmd) {
+ // TODO: Handle the exception when the length is wrong.
+ return cmd.getParams().length > 0
+ && cmd.getParams()[0] == HdmiConstants.SYSTEM_AUDIO_STATUS_ON;
+ }
+}
diff --git a/services/core/java/com/android/server/hdmi/RequestArcAction.java b/services/core/java/com/android/server/hdmi/RequestArcAction.java
index 05614a4..08ca306 100644
--- a/services/core/java/com/android/server/hdmi/RequestArcAction.java
+++ b/services/core/java/com/android/server/hdmi/RequestArcAction.java
@@ -44,28 +44,15 @@
*/
RequestArcAction(HdmiControlService service, int sourceAddress, int avrAddress) {
super(service, sourceAddress);
- verifyAddressType(sourceAddress, HdmiCec.DEVICE_TV);
- verifyAddressType(avrAddress, HdmiCec.DEVICE_AUDIO_SYSTEM);
+ HdmiUtils.verifyAddressType(sourceAddress, HdmiCec.DEVICE_TV);
+ HdmiUtils.verifyAddressType(avrAddress, HdmiCec.DEVICE_AUDIO_SYSTEM);
mAvrAddress = avrAddress;
}
- private static void verifyAddressType(int logicalAddress, int deviceType) {
- int actualDeviceType = HdmiCec.getTypeFromAddress(logicalAddress);
- if (actualDeviceType != deviceType) {
- throw new IllegalArgumentException("Device type missmatch:[Expected:" + deviceType
- + ", Actual:" + actualDeviceType);
- }
- }
-
@Override
boolean processCommand(HdmiCecMessage cmd) {
- if (mState != STATE_WATING_FOR_REQUEST_ARC_REQUEST_RESPONSE) {
- return false;
- }
-
- int src = cmd.getSource();
- if (src != mAvrAddress) {
- Slog.w(TAG, "Invalid source [Expected:" + mAvrAddress + ", Actual:" + src + "]");
+ if (mState != STATE_WATING_FOR_REQUEST_ARC_REQUEST_RESPONSE
+ || !HdmiUtils.checkCommandSource(cmd, mAvrAddress, TAG)) {
return false;
}
int opcode = cmd.getOpcode();
diff --git a/services/core/java/com/android/server/hdmi/SetArcTransmissionStateAction.java b/services/core/java/com/android/server/hdmi/SetArcTransmissionStateAction.java
index e3525d8..d53d88d 100644
--- a/services/core/java/com/android/server/hdmi/SetArcTransmissionStateAction.java
+++ b/services/core/java/com/android/server/hdmi/SetArcTransmissionStateAction.java
@@ -46,21 +46,12 @@
SetArcTransmissionStateAction(HdmiControlService service, int sourceAddress, int avrAddress,
boolean enabled) {
super(service, sourceAddress);
- verifyAddressType(sourceAddress, HdmiCec.DEVICE_TV);
- verifyAddressType(avrAddress, HdmiCec.DEVICE_AUDIO_SYSTEM);
+ HdmiUtils.verifyAddressType(sourceAddress, HdmiCec.DEVICE_TV);
+ HdmiUtils.verifyAddressType(avrAddress, HdmiCec.DEVICE_AUDIO_SYSTEM);
mAvrAddress = avrAddress;
mEnabled = enabled;
}
- // TODO: extract it as separate utility class.
- private static void verifyAddressType(int logicalAddress, int deviceType) {
- int actualDeviceType = HdmiCec.getTypeFromAddress(logicalAddress);
- if (actualDeviceType != deviceType) {
- throw new IllegalArgumentException("Device type missmatch:[Expected:" + deviceType
- + ", Actual:" + actualDeviceType);
- }
- }
-
@Override
boolean start() {
if (mEnabled) {
diff --git a/services/core/java/com/android/server/hdmi/SystemAudioAction.java b/services/core/java/com/android/server/hdmi/SystemAudioAction.java
new file mode 100644
index 0000000..dde3342
--- /dev/null
+++ b/services/core/java/com/android/server/hdmi/SystemAudioAction.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.hdmi;
+
+import android.hardware.hdmi.HdmiCec;
+import android.hardware.hdmi.HdmiCecMessage;
+
+/**
+ * Base feature action class for SystemAudioActionFromTv and SystemAudioActionFromAvr.
+ */
+abstract class SystemAudioAction extends FeatureAction {
+ private static final String TAG = "SystemAudioAction";
+
+ // State in which waits for <SetSystemAudioMode>.
+ private static final int STATE_WAIT_FOR_SET_SYSTEM_AUDIO_MODE = 1;
+
+ // State in which waits for <ReportAudioStatus>.
+ private static final int STATE_WAIT_FOR_REPORT_AUDIO_STATUS = 2;
+
+ private static final int MAX_SEND_RETRY_COUNT = 2;
+
+ private static final int ON_TIMEOUT_MS = 5000;
+ private static final int OFF_TIMEOUT_MS = TIMEOUT_MS;
+
+ // Logical address of AV Receiver.
+ protected final int mAvrLogicalAddress;
+
+ // The target audio status of the action, whether to enable the system audio mode or not.
+ protected boolean mTargetAudioStatus;
+
+ private int mSendRetryCount = 0;
+
+ /**
+ * Constructor
+ *
+ * @param service {@link HdmiControlService} instance
+ * @param sourceAddress logical address of source device (TV or STB).
+ * @param avrAddress logical address of AVR device
+ * @param targetStatus Whether to enable the system audio mode or not
+ * @throw IllegalArugmentException if device type of sourceAddress and avrAddress is invalid
+ */
+ SystemAudioAction(HdmiControlService service, int sourceAddress, int avrAddress,
+ boolean targetStatus) {
+ super(service, sourceAddress);
+ HdmiUtils.verifyAddressType(avrAddress, HdmiCec.DEVICE_AUDIO_SYSTEM);
+ mAvrLogicalAddress = avrAddress;
+ mTargetAudioStatus = targetStatus;
+ }
+
+ protected void sendSystemAudioModeRequest() {
+ int avrPhysicalAddress = mService.getAvrDeviceInfo().getPhysicalAddress();
+ HdmiCecMessage command = HdmiCecMessageBuilder.buildSystemAudioModeRequest(mSourceAddress,
+ mAvrLogicalAddress, avrPhysicalAddress, mTargetAudioStatus);
+ sendCommand(command, new HdmiControlService.SendMessageCallback() {
+ @Override
+ public void onSendCompleted(int error) {
+ if (error == HdmiControlService.SEND_RESULT_SUCCESS) {
+ mState = STATE_WAIT_FOR_SET_SYSTEM_AUDIO_MODE;
+ addTimer(mState, mTargetAudioStatus ? ON_TIMEOUT_MS : OFF_TIMEOUT_MS);
+ } else {
+ setSystemAudioMode(false);
+ finish();
+ }
+ }
+ });
+ }
+
+ private void handleSendSystemAudioModeRequestTimeout() {
+ if (!mTargetAudioStatus // Don't retry for Off case.
+ || mSendRetryCount++ >= MAX_SEND_RETRY_COUNT) {
+ setSystemAudioMode(false);
+ finish();
+ return;
+ }
+ sendSystemAudioModeRequest();
+ }
+
+ protected void setSystemAudioMode(boolean mode) {
+ mService.setSystemAudioMode(mode);
+ }
+
+ protected void sendGiveAudioStatus() {
+ HdmiCecMessage command = HdmiCecMessageBuilder.buildGiveAudioStatus(mSourceAddress,
+ mAvrLogicalAddress);
+ sendCommand(command, new HdmiControlService.SendMessageCallback() {
+ @Override
+ public void onSendCompleted(int error) {
+ if (error == HdmiControlService.SEND_RESULT_SUCCESS) {
+ mState = STATE_WAIT_FOR_REPORT_AUDIO_STATUS;
+ addTimer(mState, TIMEOUT_MS);
+ } else {
+ handleSendGiveAudioStatusFailure();
+ }
+ }
+ });
+ }
+
+ private void handleSendGiveAudioStatusFailure() {
+ // TODO: Notify the failure status.
+
+ int uiCommand = mService.getSystemAudioMode()
+ ? HdmiConstants.UI_COMMAND_RESTORE_VOLUME_FUNCTION // SystemAudioMode: ON
+ : HdmiConstants.UI_COMMAND_MUTE_FUNCTION; // SystemAudioMode: OFF
+ sendUserControlPressedAndReleased(uiCommand);
+ finish();
+ }
+
+ private void sendUserControlPressedAndReleased(int uiCommand) {
+ sendCommand(HdmiCecMessageBuilder.buildUserControlPressed(
+ mSourceAddress, mAvrLogicalAddress, uiCommand));
+ sendCommand(HdmiCecMessageBuilder.buildUserControlReleased(
+ mSourceAddress, mAvrLogicalAddress));
+ }
+
+ @Override
+ final boolean processCommand(HdmiCecMessage cmd) {
+ switch (mState) {
+ case STATE_WAIT_FOR_SET_SYSTEM_AUDIO_MODE:
+ // TODO: Handle <FeatureAbort> of <SystemAudioModeRequest>
+ if (cmd.getOpcode() != HdmiCec.MESSAGE_SET_SYSTEM_AUDIO_MODE
+ || !HdmiUtils.checkCommandSource(cmd, mAvrLogicalAddress, TAG)) {
+ return false;
+ }
+ boolean receivedStatus = HdmiUtils.parseCommandParamSystemAudioStatus(cmd);
+ if (receivedStatus == mTargetAudioStatus) {
+ setSystemAudioMode(receivedStatus);
+ sendGiveAudioStatus();
+ } else {
+ // Unexpected response, consider the request is newly initiated by AVR.
+ // To return 'false' will initiate new SystemAudioActionFromAvr by the control
+ // service.
+ finish();
+ return false;
+ }
+ return true;
+
+ case STATE_WAIT_FOR_REPORT_AUDIO_STATUS:
+ // TODO: Handle <FeatureAbort> of <GiveAudioStatus>
+ if (cmd.getOpcode() != HdmiCec.MESSAGE_REPORT_AUDIO_STATUS
+ || !HdmiUtils.checkCommandSource(cmd, mAvrLogicalAddress, TAG)) {
+ return false;
+ }
+ byte[] params = cmd.getParams();
+ if (params.length > 0) {
+ boolean mute = (params[0] & 0x80) == 0x80;
+ int volume = params[0] & 0x7F;
+ mService.setAudioStatus(mute, volume);
+ if (mTargetAudioStatus && mute || !mTargetAudioStatus && !mute) {
+ // Toggle AVR's mute status to match with the system audio status.
+ sendUserControlPressedAndReleased(HdmiConstants.UI_COMMAND_MUTE);
+ }
+ }
+ finish();
+ return true;
+ }
+ return false;
+ }
+
+ protected void removeSystemAudioActionInProgress() {
+ mService.removeActionExcept(SystemAudioActionFromTv.class, this);
+ mService.removeActionExcept(SystemAudioActionFromAvr.class, this);
+ }
+
+ @Override
+ final void handleTimerEvent(int state) {
+ if (mState != state) {
+ return;
+ }
+ switch (mState) {
+ case STATE_WAIT_FOR_SET_SYSTEM_AUDIO_MODE:
+ handleSendSystemAudioModeRequestTimeout();
+ return;
+ case STATE_WAIT_FOR_REPORT_AUDIO_STATUS:
+ handleSendGiveAudioStatusFailure();
+ return;
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/hdmi/SystemAudioActionFromAvr.java b/services/core/java/com/android/server/hdmi/SystemAudioActionFromAvr.java
new file mode 100644
index 0000000..c5eb44b
--- /dev/null
+++ b/services/core/java/com/android/server/hdmi/SystemAudioActionFromAvr.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.hdmi;
+
+import android.hardware.hdmi.HdmiCec;
+
+/**
+ * Feature action that handles System Audio initiated by AVR devices.
+ */
+final class SystemAudioActionFromAvr extends SystemAudioAction {
+ /**
+ * Constructor
+ *
+ * @param service {@link HdmiControlService} instance
+ * @param tvAddress logical address of TV device
+ * @param avrAddress logical address of AVR device
+ * @param targetStatus Whether to enable the system audio mode or not
+ * @throw IllegalArugmentException if device type of tvAddress and avrAddress is invalid
+ */
+ SystemAudioActionFromAvr(HdmiControlService service, int tvAddress, int avrAddress,
+ boolean targetStatus) {
+ super(service, tvAddress, avrAddress, targetStatus);
+ HdmiUtils.verifyAddressType(tvAddress, HdmiCec.DEVICE_TV);
+ }
+
+ @Override
+ boolean start() {
+ removeSystemAudioActionInProgress();
+ handleSystemAudioActionFromAvr();
+ return true;
+ }
+
+ private void handleSystemAudioActionFromAvr() {
+ if (mTargetAudioStatus == mService.getSystemAudioMode()) {
+ finish();
+ return;
+ }
+ if (mService.isInPresetInstallationMode()) {
+ sendCommand(HdmiCecMessageBuilder.buildFeatureAbortCommand(
+ mSourceAddress, mAvrLogicalAddress,
+ HdmiCec.MESSAGE_SET_SYSTEM_AUDIO_MODE, HdmiConstants.ABORT_REFUSED));
+ mTargetAudioStatus = false;
+ sendSystemAudioModeRequest();
+ return;
+ }
+ // TODO: Stop the action for System Audio Mode initialization if it is running.
+ if (mTargetAudioStatus) {
+ setSystemAudioMode(true);
+ sendGiveAudioStatus();
+ } else {
+ setSystemAudioMode(false);
+ finish();
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/hdmi/SystemAudioActionFromTv.java b/services/core/java/com/android/server/hdmi/SystemAudioActionFromTv.java
new file mode 100644
index 0000000..9994de6
--- /dev/null
+++ b/services/core/java/com/android/server/hdmi/SystemAudioActionFromTv.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.hdmi;
+
+import android.hardware.hdmi.HdmiCec;
+
+
+/**
+ * Feature action that handles System Audio initiated by TV devices.
+ */
+final class SystemAudioActionFromTv extends SystemAudioAction {
+ /**
+ * Constructor
+ *
+ * @param service {@link HdmiControlService} instance
+ * @param tvAddress logical address of TV device
+ * @param avrAddress logical address of AVR device
+ * @param targetStatus Whether to enable the system audio mode or not
+ * @throw IllegalArugmentException if device type of tvAddress is invalid
+ */
+ SystemAudioActionFromTv(HdmiControlService service, int tvAddress, int avrAddress,
+ boolean targetStatus) {
+ super(service, tvAddress, avrAddress, targetStatus);
+ HdmiUtils.verifyAddressType(tvAddress, HdmiCec.DEVICE_TV);
+ }
+
+ @Override
+ boolean start() {
+ // TODO: Check HDMI-CEC is enabled.
+ // TODO: Move to the waiting state if currently a routing change is in progress.
+
+ removeSystemAudioActionInProgress();
+ sendSystemAudioModeRequest();
+ return true;
+ }
+}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 13cc98c..bb93663 100755
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -40,6 +40,7 @@
import com.android.internal.app.IMediaContainerService;
import com.android.internal.app.ResolverActivity;
import com.android.internal.content.NativeLibraryHelper;
+import com.android.internal.content.NativeLibraryHelper.ApkHandle;
import com.android.internal.content.PackageHelper;
import com.android.internal.util.FastPrintWriter;
import com.android.internal.util.FastXmlSerializer;
@@ -4148,7 +4149,7 @@
continue;
}
PackageParser.Package pkg = scanPackageLI(file,
- flags|PackageParser.PARSE_MUST_BE_APK, scanMode, currentTime, null);
+ flags|PackageParser.PARSE_MUST_BE_APK, scanMode, currentTime, null, null);
// Don't mess around with apps in system partition.
if (pkg == null && (flags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
mLastScanError == PackageManager.INSTALL_FAILED_INVALID_APK) {
@@ -4215,7 +4216,7 @@
* Returns null in case of errors and the error code is stored in mLastScanError
*/
private PackageParser.Package scanPackageLI(File scanFile,
- int parseFlags, int scanMode, long currentTime, UserHandle user) {
+ int parseFlags, int scanMode, long currentTime, UserHandle user, String abiOverride) {
mLastScanError = PackageManager.INSTALL_SUCCEEDED;
String scanPath = scanFile.getPath();
if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanPath);
@@ -4283,7 +4284,7 @@
mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
return null;
} else {
- // The current app on the system partion is better than
+ // The current app on the system partition is better than
// what we have updated to on the data partition; switch
// back to the system partition version.
// At this point, its safely assumed that package installation for
@@ -4402,7 +4403,7 @@
setApplicationInfoPaths(pkg, codePath, resPath);
// Note that we invoke the following method only if we are about to unpack an application
PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanMode
- | SCAN_UPDATE_SIGNATURE, currentTime, user);
+ | SCAN_UPDATE_SIGNATURE, currentTime, user, abiOverride);
/*
* If the system app should be overridden by a previously installed
@@ -4945,7 +4946,7 @@
}
private PackageParser.Package scanPackageLI(PackageParser.Package pkg,
- int parseFlags, int scanMode, long currentTime, UserHandle user) {
+ int parseFlags, int scanMode, long currentTime, UserHandle user, String abiOverride) {
File scanFile = new File(pkg.mScanPath);
if (scanFile == null || pkg.applicationInfo.sourceDir == null ||
pkg.applicationInfo.publicSourceDir == null) {
@@ -5395,7 +5396,22 @@
* only for non-system apps and system app upgrades.
*/
if (pkg.applicationInfo.nativeLibraryDir != null) {
+ final NativeLibraryHelper.ApkHandle handle = new NativeLibraryHelper.ApkHandle(scanFile);
try {
+ // Enable gross and lame hacks for apps that are built with old
+ // SDK tools. We must scan their APKs for renderscript bitcode and
+ // not launch them if it's present. Don't bother checking on devices
+ // that don't have 64 bit support.
+ String[] abiList = Build.SUPPORTED_ABIS;
+ boolean hasLegacyRenderscriptBitcode = false;
+ if (abiOverride != null) {
+ abiList = new String[] { abiOverride };
+ } else if (Build.SUPPORTED_64_BIT_ABIS.length > 0 &&
+ NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
+ abiList = Build.SUPPORTED_32_BIT_ABIS;
+ hasLegacyRenderscriptBitcode = true;
+ }
+
File nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir);
final String dataPathString = dataPath.getCanonicalPath();
@@ -5411,21 +5427,26 @@
Log.i(TAG, "removed obsolete native libraries for system package "
+ path);
}
-
- setInternalAppAbi(pkg, pkgSetting);
+ if (abiOverride != null || hasLegacyRenderscriptBitcode) {
+ pkg.applicationInfo.cpuAbi = abiList[0];
+ pkgSetting.cpuAbiString = abiList[0];
+ } else {
+ setInternalAppAbi(pkg, pkgSetting);
+ }
} else {
if (!isForwardLocked(pkg) && !isExternal(pkg)) {
/*
- * Update native library dir if it starts with
- * /data/data
- */
+ * Update native library dir if it starts with
+ * /data/data
+ */
if (nativeLibraryDir.getPath().startsWith(dataPathString)) {
setInternalAppNativeLibraryPath(pkg, pkgSetting);
nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir);
}
try {
- int copyRet = copyNativeLibrariesForInternalApp(scanFile, nativeLibraryDir);
+ int copyRet = copyNativeLibrariesForInternalApp(handle,
+ nativeLibraryDir, abiList);
if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
Slog.e(TAG, "Unable to copy native libraries");
mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
@@ -5435,7 +5456,9 @@
// We've successfully copied native libraries across, so we make a
// note of what ABI we're using
if (copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
- pkg.applicationInfo.cpuAbi = Build.SUPPORTED_ABIS[copyRet];
+ pkg.applicationInfo.cpuAbi = abiList[copyRet];
+ } else if (abiOverride != null || hasLegacyRenderscriptBitcode) {
+ pkg.applicationInfo.cpuAbi = abiList[0];
} else {
pkg.applicationInfo.cpuAbi = null;
}
@@ -5452,20 +5475,22 @@
// to clean this up but we'll need to change the interface between this service
// and IMediaContainerService (but doing so will spread this logic out, rather
// than centralizing it).
- final NativeLibraryHelper.ApkHandle handle = new NativeLibraryHelper.ApkHandle(scanFile);
- final int abi = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_ABIS);
+ final int abi = NativeLibraryHelper.findSupportedAbi(handle, abiList);
if (abi >= 0) {
- pkg.applicationInfo.cpuAbi = Build.SUPPORTED_ABIS[abi];
+ pkg.applicationInfo.cpuAbi = abiList[abi];
} else if (abi == PackageManager.NO_NATIVE_LIBRARIES) {
// Note that (non upgraded) system apps will not have any native
// libraries bundled in their APK, but we're guaranteed not to be
// such an app at this point.
- pkg.applicationInfo.cpuAbi = null;
+ if (abiOverride != null || hasLegacyRenderscriptBitcode) {
+ pkg.applicationInfo.cpuAbi = abiList[0];
+ } else {
+ pkg.applicationInfo.cpuAbi = null;
+ }
} else {
mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
return null;
}
- handle.close();
}
if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path);
@@ -5482,8 +5507,12 @@
}
}
}
+
+ pkgSetting.cpuAbiString = pkg.applicationInfo.cpuAbi;
} catch (IOException ioe) {
Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
+ } finally {
+ handle.close();
}
}
pkg.mScanPath = path;
@@ -6175,8 +6204,8 @@
}
}
- private static int copyNativeLibrariesForInternalApp(File scanFile, final File nativeLibraryDir)
- throws IOException {
+ private static int copyNativeLibrariesForInternalApp(ApkHandle handle,
+ final File nativeLibraryDir, String[] abiList) throws IOException {
if (!nativeLibraryDir.isDirectory()) {
nativeLibraryDir.delete();
@@ -6198,21 +6227,16 @@
* If this is an internal application or our nativeLibraryPath points to
* the app-lib directory, unpack the libraries if necessary.
*/
- final NativeLibraryHelper.ApkHandle handle = new NativeLibraryHelper.ApkHandle(scanFile);
- try {
- int abi = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_ABIS);
- if (abi >= 0) {
- int copyRet = NativeLibraryHelper.copyNativeBinariesIfNeededLI(handle,
- nativeLibraryDir, Build.SUPPORTED_ABIS[abi]);
- if (copyRet != PackageManager.INSTALL_SUCCEEDED) {
- return copyRet;
- }
+ int abi = NativeLibraryHelper.findSupportedAbi(handle, abiList);
+ if (abi >= 0) {
+ int copyRet = NativeLibraryHelper.copyNativeBinariesIfNeededLI(handle,
+ nativeLibraryDir, Build.SUPPORTED_ABIS[abi]);
+ if (copyRet != PackageManager.INSTALL_SUCCEEDED) {
+ return copyRet;
}
-
- return abi;
- } finally {
- handle.close();
}
+
+ return abi;
}
private void killApplication(String pkgName, int appId, String reason) {
@@ -7536,7 +7560,7 @@
}
p = scanPackageLI(fullPath, flags,
SCAN_MONITOR | SCAN_NO_PATHS | SCAN_UPDATE_TIME,
- System.currentTimeMillis(), UserHandle.ALL);
+ System.currentTimeMillis(), UserHandle.ALL, null);
if (p != null) {
/*
* TODO this seems dangerous as the package may have
@@ -7657,6 +7681,16 @@
if (observer == null && observer2 == null) {
throw new IllegalArgumentException("No install observer supplied");
}
+ installPackageWithVerificationEncryptionAndAbiOverrideEtc(packageURI, observer, observer2,
+ flags, installerPackageName, verificationParams, encryptionParams, null);
+ }
+
+ @Override
+ public void installPackageWithVerificationEncryptionAndAbiOverrideEtc(Uri packageURI,
+ IPackageInstallObserver observer, IPackageInstallObserver2 observer2,
+ int flags, String installerPackageName,
+ VerificationParams verificationParams, ContainerEncryptionParams encryptionParams,
+ String packageAbiOverride) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
null);
@@ -7696,7 +7730,8 @@
final Message msg = mHandler.obtainMessage(INIT_COPY);
msg.obj = new InstallParams(packageURI, observer, observer2, filteredFlags,
- installerPackageName, verificationParams, encryptionParams, user);
+ installerPackageName, verificationParams, encryptionParams, user,
+ packageAbiOverride);
mHandler.sendMessage(msg);
}
@@ -8405,11 +8440,14 @@
private int mRet;
private File mTempPackage;
final ContainerEncryptionParams encryptionParams;
+ final String packageAbiOverride;
+ final String packageInstructionSetOverride;
InstallParams(Uri packageURI,
IPackageInstallObserver observer, IPackageInstallObserver2 observer2,
int flags, String installerPackageName, VerificationParams verificationParams,
- ContainerEncryptionParams encryptionParams, UserHandle user) {
+ ContainerEncryptionParams encryptionParams, UserHandle user,
+ String packageAbiOverride) {
super(user);
this.mPackageURI = packageURI;
this.flags = flags;
@@ -8418,6 +8456,9 @@
this.installerPackageName = installerPackageName;
this.verificationParams = verificationParams;
this.encryptionParams = encryptionParams;
+ this.packageAbiOverride = packageAbiOverride;
+ this.packageInstructionSetOverride = (packageAbiOverride == null) ?
+ packageAbiOverride : VMRuntime.getInstructionSet(packageAbiOverride);
}
@Override
@@ -8563,7 +8604,7 @@
// Remote call to find out default install location
final String packageFilePath = packageFile.getAbsolutePath();
pkgLite = mContainerService.getMinimalPackageInfo(packageFilePath, flags,
- lowThreshold);
+ lowThreshold, packageAbiOverride);
/*
* If we have too little free space, try to free cache
@@ -8572,10 +8613,10 @@
if (pkgLite.recommendedInstallLocation
== PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
final long size = mContainerService.calculateInstalledSize(
- packageFilePath, isForwardLocked());
+ packageFilePath, isForwardLocked(), packageAbiOverride);
if (mInstaller.freeCache(size + lowThreshold) >= 0) {
pkgLite = mContainerService.getMinimalPackageInfo(packageFilePath,
- flags, lowThreshold);
+ flags, lowThreshold, packageAbiOverride);
}
/*
* The cache free must have deleted the file we
@@ -8995,11 +9036,12 @@
final ManifestDigest manifestDigest;
final UserHandle user;
final String instructionSet;
+ final String abiOverride;
InstallArgs(Uri packageURI,
IPackageInstallObserver observer, IPackageInstallObserver2 observer2,
int flags, String installerPackageName, ManifestDigest manifestDigest,
- UserHandle user, String instructionSet) {
+ UserHandle user, String instructionSet, String abiOverride) {
this.packageURI = packageURI;
this.flags = flags;
this.observer = observer;
@@ -9008,6 +9050,7 @@
this.manifestDigest = manifestDigest;
this.user = user;
this.instructionSet = instructionSet;
+ this.abiOverride = abiOverride;
}
abstract void createCopyFile();
@@ -9063,12 +9106,13 @@
FileInstallArgs(InstallParams params) {
super(params.getPackageUri(), params.observer, params.observer2, params.flags,
params.installerPackageName, params.getManifestDigest(),
- params.getUser(), null /* instruction set */);
+ params.getUser(), params.packageInstructionSetOverride,
+ params.packageAbiOverride);
}
FileInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath,
String instructionSet) {
- super(null, null, null, 0, null, null, null, instructionSet);
+ super(null, null, null, 0, null, null, null, instructionSet, null);
File codeFile = new File(fullCodePath);
installDir = codeFile.getParentFile();
codeFileName = fullCodePath;
@@ -9077,7 +9121,7 @@
}
FileInstallArgs(Uri packageURI, String pkgName, String dataDir, String instructionSet) {
- super(packageURI, null, null, 0, null, null, null, instructionSet);
+ super(packageURI, null, null, 0, null, null, null, instructionSet, null);
installDir = isFwdLocked() ? mDrmAppPrivateInstallDir : mAppInstallDir;
String apkName = getNextCodePath(null, pkgName, ".apk");
codeFileName = new File(installDir, apkName + ".apk").getPath();
@@ -9181,14 +9225,26 @@
NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryFile);
nativeLibraryFile.delete();
}
+
+ final NativeLibraryHelper.ApkHandle handle = new NativeLibraryHelper.ApkHandle(codeFile);
+ String[] abiList = (abiOverride != null) ?
+ new String[] { abiOverride } : Build.SUPPORTED_ABIS;
try {
- int copyRet = copyNativeLibrariesForInternalApp(codeFile, nativeLibraryFile);
+ if (Build.SUPPORTED_64_BIT_ABIS.length > 0 &&
+ abiOverride == null &&
+ NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
+ abiList = Build.SUPPORTED_32_BIT_ABIS;
+ }
+
+ int copyRet = copyNativeLibrariesForInternalApp(handle, nativeLibraryFile, abiList);
if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
return copyRet;
}
} catch (IOException e) {
Slog.e(TAG, "Copying native libraries failed", e);
ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
+ } finally {
+ handle.close();
}
return ret;
@@ -9403,14 +9459,15 @@
AsecInstallArgs(InstallParams params) {
super(params.getPackageUri(), params.observer, params.observer2, params.flags,
params.installerPackageName, params.getManifestDigest(),
- params.getUser(), null /* instruction set */);
+ params.getUser(), params.packageInstructionSetOverride,
+ params.packageAbiOverride);
}
AsecInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath,
String instructionSet, boolean isExternal, boolean isForwardLocked) {
super(null, null, null, (isExternal ? PackageManager.INSTALL_EXTERNAL : 0)
| (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0),
- null, null, null, instructionSet);
+ null, null, null, instructionSet, null);
// Extract cid from fullCodePath
int eidx = fullCodePath.lastIndexOf("/");
String subStr1 = fullCodePath.substring(0, eidx);
@@ -9422,7 +9479,7 @@
AsecInstallArgs(String cid, String instructionSet, boolean isForwardLocked) {
super(null, null, null, (isAsecExternal(cid) ? PackageManager.INSTALL_EXTERNAL : 0)
| (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0),
- null, null, null, instructionSet);
+ null, null, null, instructionSet, null);
this.cid = cid;
setCachePath(PackageHelper.getSdDir(cid));
}
@@ -9431,7 +9488,7 @@
boolean isExternal, boolean isForwardLocked) {
super(packageURI, null, null, (isExternal ? PackageManager.INSTALL_EXTERNAL : 0)
| (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0),
- null, null, null, instructionSet);
+ null, null, null, instructionSet, null);
this.cid = cid;
}
@@ -9443,7 +9500,7 @@
try {
mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
Intent.FLAG_GRANT_READ_URI_PERMISSION);
- return imcs.checkExternalFreeStorage(packageURI, isFwdLocked());
+ return imcs.checkExternalFreeStorage(packageURI, isFwdLocked(), abiOverride);
} finally {
mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
@@ -9469,7 +9526,8 @@
mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
Intent.FLAG_GRANT_READ_URI_PERMISSION);
newCachePath = imcs.copyResourceToContainer(packageURI, cid, getEncryptKey(),
- RES_FILE_NAME, PUBLIC_RES_FILE_NAME, isExternal(), isFwdLocked());
+ RES_FILE_NAME, PUBLIC_RES_FILE_NAME, isExternal(), isFwdLocked(),
+ abiOverride);
} finally {
mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
@@ -9777,7 +9835,7 @@
*/
private void installNewPackageLI(PackageParser.Package pkg,
int parseFlags, int scanMode, UserHandle user,
- String installerPackageName, PackageInstalledInfo res) {
+ String installerPackageName, PackageInstalledInfo res, String abiOverride) {
// Remember this for later, in case we need to rollback this install
String pkgName = pkg.packageName;
@@ -9805,7 +9863,7 @@
}
mLastScanError = PackageManager.INSTALL_SUCCEEDED;
PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, scanMode,
- System.currentTimeMillis(), user);
+ System.currentTimeMillis(), user, abiOverride);
if (newPackage == null) {
Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath);
if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) {
@@ -9832,7 +9890,7 @@
private void replacePackageLI(PackageParser.Package pkg,
int parseFlags, int scanMode, UserHandle user,
- String installerPackageName, PackageInstalledInfo res) {
+ String installerPackageName, PackageInstalledInfo res, String abiOverride) {
PackageParser.Package oldPackage;
String pkgName = pkg.packageName;
@@ -9861,17 +9919,19 @@
boolean sysPkg = (isSystemApp(oldPackage));
if (sysPkg) {
replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanMode,
- user, allUsers, perUserInstalled, installerPackageName, res);
+ user, allUsers, perUserInstalled, installerPackageName, res,
+ abiOverride);
} else {
replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanMode,
- user, allUsers, perUserInstalled, installerPackageName, res);
+ user, allUsers, perUserInstalled, installerPackageName, res,
+ abiOverride);
}
}
private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage,
PackageParser.Package pkg, int parseFlags, int scanMode, UserHandle user,
int[] allUsers, boolean[] perUserInstalled,
- String installerPackageName, PackageInstalledInfo res) {
+ String installerPackageName, PackageInstalledInfo res, String abiOverride) {
PackageParser.Package newPackage = null;
String pkgName = deletedPackage.packageName;
boolean deletedPkg = true;
@@ -9896,7 +9956,7 @@
// Successfully deleted the old package. Now proceed with re-installation
mLastScanError = PackageManager.INSTALL_SUCCEEDED;
newPackage = scanPackageLI(pkg, parseFlags, scanMode | SCAN_UPDATE_TIME,
- System.currentTimeMillis(), user);
+ System.currentTimeMillis(), user, abiOverride);
if (newPackage == null) {
Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath);
if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) {
@@ -9925,7 +9985,7 @@
}
// Since we failed to install the new package we need to restore the old
// package that we deleted.
- if(deletedPkg) {
+ if (deletedPkg) {
if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
File restoreFile = new File(deletedPackage.mPath);
// Parse old package
@@ -9936,7 +9996,7 @@
int oldScanMode = (oldOnSd ? 0 : SCAN_MONITOR) | SCAN_UPDATE_SIGNATURE
| SCAN_UPDATE_TIME;
if (scanPackageLI(restoreFile, oldParseFlags, oldScanMode,
- origUpdateTime, null) == null) {
+ origUpdateTime, null, null) == null) {
Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade");
return;
}
@@ -9956,7 +10016,7 @@
private void replaceSystemPackageLI(PackageParser.Package deletedPackage,
PackageParser.Package pkg, int parseFlags, int scanMode, UserHandle user,
int[] allUsers, boolean[] perUserInstalled,
- String installerPackageName, PackageInstalledInfo res) {
+ String installerPackageName, PackageInstalledInfo res, String abiOverride) {
if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
+ ", old=" + deletedPackage);
PackageParser.Package newPackage = null;
@@ -10010,7 +10070,7 @@
// Successfully disabled the old package. Now proceed with re-installation
res.returnCode = mLastScanError = PackageManager.INSTALL_SUCCEEDED;
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
- newPackage = scanPackageLI(pkg, parseFlags, scanMode, 0, user);
+ newPackage = scanPackageLI(pkg, parseFlags, scanMode, 0, user, abiOverride);
if (newPackage == null) {
Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath);
if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) {
@@ -10044,7 +10104,7 @@
removeInstalledPackageLI(newPackage, true);
}
// Add back the old system package
- scanPackageLI(oldPkg, parseFlags, SCAN_MONITOR | SCAN_UPDATE_SIGNATURE, 0, user);
+ scanPackageLI(oldPkg, parseFlags, SCAN_MONITOR | SCAN_UPDATE_SIGNATURE, 0, user, null);
// Restore the old system information in Settings
synchronized(mPackages) {
if (updatedSettings) {
@@ -10278,10 +10338,10 @@
pkg.applicationInfo.nativeLibraryDir = args.getNativeLibraryPath();
if (replace) {
replacePackageLI(pkg, parseFlags, scanMode, args.user,
- installerPackageName, res);
+ installerPackageName, res, args.abiOverride);
} else {
installNewPackageLI(pkg, parseFlags, scanMode | SCAN_DELETE_DATA_ON_FAILURES, args.user,
- installerPackageName, res);
+ installerPackageName, res, args.abiOverride);
}
synchronized (mPackages) {
final PackageSetting ps = mSettings.mPackages.get(pkgName);
@@ -10698,7 +10758,7 @@
parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
}
PackageParser.Package newPkg = scanPackageLI(disabledPs.codePath,
- parseFlags, SCAN_MONITOR | SCAN_NO_PATHS, 0, null);
+ parseFlags, SCAN_MONITOR | SCAN_NO_PATHS, 0, null, null);
if (newPkg == null) {
Slog.w(TAG, "Failed to restore system package:" + newPs.name
@@ -12511,7 +12571,7 @@
doGc = true;
synchronized (mInstallLock) {
final PackageParser.Package pkg = scanPackageLI(new File(codePath), parseFlags,
- 0, 0, null);
+ 0, 0, null, null);
// Scan the package
if (pkg != null) {
/*
diff --git a/services/core/java/com/android/server/tv/TvInputHal.java b/services/core/java/com/android/server/tv/TvInputHal.java
index 4bdd2be..34168a8 100644
--- a/services/core/java/com/android/server/tv/TvInputHal.java
+++ b/services/core/java/com/android/server/tv/TvInputHal.java
@@ -16,10 +16,10 @@
package com.android.server.tv;
+import android.media.tv.TvInputHardwareInfo;
+import android.media.tv.TvStreamConfig;
import android.os.Handler;
import android.os.HandlerThread;
-import android.tv.TvInputHardwareInfo;
-import android.tv.TvStreamConfig;
import android.view.Surface;
/**
diff --git a/services/core/java/com/android/server/tv/TvInputHardwareManager.java b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
index b95b0f0..e34f42b 100644
--- a/services/core/java/com/android/server/tv/TvInputHardwareManager.java
+++ b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
@@ -17,12 +17,12 @@
package com.android.server.tv;
import android.content.Context;
+import android.media.tv.ITvInputHardware;
+import android.media.tv.ITvInputHardwareCallback;
+import android.media.tv.TvInputHardwareInfo;
+import android.media.tv.TvStreamConfig;
import android.os.IBinder;
import android.os.RemoteException;
-import android.tv.ITvInputHardware;
-import android.tv.ITvInputHardwareCallback;
-import android.tv.TvInputHardwareInfo;
-import android.tv.TvStreamConfig;
import android.util.Slog;
import android.util.SparseArray;
import android.view.KeyEvent;
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index e52f218..3d4e4b0 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -31,6 +31,18 @@
import android.content.pm.ServiceInfo;
import android.database.Cursor;
import android.graphics.Rect;
+import android.media.tv.ITvInputClient;
+import android.media.tv.ITvInputHardware;
+import android.media.tv.ITvInputHardwareCallback;
+import android.media.tv.ITvInputManager;
+import android.media.tv.ITvInputService;
+import android.media.tv.ITvInputServiceCallback;
+import android.media.tv.ITvInputSession;
+import android.media.tv.ITvInputSessionCallback;
+import android.media.tv.TvContract;
+import android.media.tv.TvInputHardwareInfo;
+import android.media.tv.TvInputInfo;
+import android.media.tv.TvInputService;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
@@ -41,18 +53,6 @@
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
-import android.provider.TvContract;
-import android.tv.ITvInputClient;
-import android.tv.ITvInputHardware;
-import android.tv.ITvInputHardwareCallback;
-import android.tv.ITvInputManager;
-import android.tv.ITvInputService;
-import android.tv.ITvInputServiceCallback;
-import android.tv.ITvInputSession;
-import android.tv.ITvInputSessionCallback;
-import android.tv.TvInputHardwareInfo;
-import android.tv.TvInputInfo;
-import android.tv.TvInputService;
import android.util.Slog;
import android.util.SparseArray;
import android.view.InputChannel;
diff --git a/services/core/jni/com_android_server_tv_TvInputHal.cpp b/services/core/jni/com_android_server_tv_TvInputHal.cpp
index f0c4f3a..afe629d 100644
--- a/services/core/jni/com_android_server_tv_TvInputHal.cpp
+++ b/services/core/jni/com_android_server_tv_TvInputHal.cpp
@@ -316,7 +316,7 @@
(void*) nativeOpen },
{ "nativeSetSurface", "(JIILandroid/view/Surface;)I",
(void*) nativeSetSurface },
- { "nativeGetStreamConfigs", "(JII)[Landroid/tv/TvStreamConfig;",
+ { "nativeGetStreamConfigs", "(JII)[Landroid/media/tv/TvStreamConfig;",
(void*) nativeGetStreamConfigs },
{ "nativeClose", "(J)V",
(void*) nativeClose },
@@ -346,10 +346,10 @@
gTvInputHalClassInfo.streamConfigsChanged, clazz,
"streamConfigsChangedFromNative", "(I)V");
- FIND_CLASS(gTvStreamConfigClassInfo.clazz, "android/tv/TvStreamConfig");
+ FIND_CLASS(gTvStreamConfigClassInfo.clazz, "android/media/tv/TvStreamConfig");
gTvStreamConfigClassInfo.clazz = jclass(env->NewGlobalRef(gTvStreamConfigClassInfo.clazz));
- FIND_CLASS(gTvStreamConfigBuilderClassInfo.clazz, "android/tv/TvStreamConfig$Builder");
+ FIND_CLASS(gTvStreamConfigBuilderClassInfo.clazz, "android/media/tv/TvStreamConfig$Builder");
gTvStreamConfigBuilderClassInfo.clazz =
jclass(env->NewGlobalRef(gTvStreamConfigBuilderClassInfo.clazz));
@@ -360,27 +360,27 @@
GET_METHOD_ID(
gTvStreamConfigBuilderClassInfo.streamId,
gTvStreamConfigBuilderClassInfo.clazz,
- "streamId", "(I)Landroid/tv/TvStreamConfig$Builder;");
+ "streamId", "(I)Landroid/media/tv/TvStreamConfig$Builder;");
GET_METHOD_ID(
gTvStreamConfigBuilderClassInfo.type,
gTvStreamConfigBuilderClassInfo.clazz,
- "type", "(I)Landroid/tv/TvStreamConfig$Builder;");
+ "type", "(I)Landroid/media/tv/TvStreamConfig$Builder;");
GET_METHOD_ID(
gTvStreamConfigBuilderClassInfo.maxWidth,
gTvStreamConfigBuilderClassInfo.clazz,
- "maxWidth", "(I)Landroid/tv/TvStreamConfig$Builder;");
+ "maxWidth", "(I)Landroid/media/tv/TvStreamConfig$Builder;");
GET_METHOD_ID(
gTvStreamConfigBuilderClassInfo.maxHeight,
gTvStreamConfigBuilderClassInfo.clazz,
- "maxHeight", "(I)Landroid/tv/TvStreamConfig$Builder;");
+ "maxHeight", "(I)Landroid/media/tv/TvStreamConfig$Builder;");
GET_METHOD_ID(
gTvStreamConfigBuilderClassInfo.generation,
gTvStreamConfigBuilderClassInfo.clazz,
- "generation", "(I)Landroid/tv/TvStreamConfig$Builder;");
+ "generation", "(I)Landroid/media/tv/TvStreamConfig$Builder;");
GET_METHOD_ID(
gTvStreamConfigBuilderClassInfo.build,
gTvStreamConfigBuilderClassInfo.clazz,
- "build", "()Landroid/tv/TvStreamConfig;");
+ "build", "()Landroid/media/tv/TvStreamConfig;");
return 0;
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 164fe05..18ece5b 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -29,6 +29,7 @@
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.media.AudioService;
+import android.media.tv.TvInputManager;
import android.os.Build;
import android.os.Environment;
import android.os.FactoryTest;
@@ -43,7 +44,6 @@
import android.os.SystemProperties;
import android.os.UserHandle;
import android.service.dreams.DreamService;
-import android.tv.TvInputManager;
import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.Log;
diff --git a/tests/RenderThreadTest/src/com/example/renderthread/MainActivity.java b/tests/RenderThreadTest/src/com/example/renderthread/MainActivity.java
index c7715ad..fc5426c 100644
--- a/tests/RenderThreadTest/src/com/example/renderthread/MainActivity.java
+++ b/tests/RenderThreadTest/src/com/example/renderthread/MainActivity.java
@@ -43,7 +43,6 @@
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- HardwareRenderer.sUseRenderThread = true;
setContentView(R.layout.activity_main);
ListView lv = (ListView) findViewById(android.R.id.list);
lv.setDrawSelectorOnTop(true);
diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable22.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable22.xml
new file mode 100644
index 0000000..8d38cb5
--- /dev/null
+++ b/tests/VectorDrawableTest/res/drawable/vector_drawable22.xml
@@ -0,0 +1,72 @@
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <size
+ android:height="64dp"
+ android:width="64dp" />
+
+ <viewport
+ android:viewportHeight="400"
+ android:viewportWidth="400" />
+
+ <group android:name="backgroundGroup" >
+ <path
+ android:name="background1"
+ android:fill="#80000000"
+ android:pathData="M 0,0 l 200,0 l 0, 200 l -200, 0 z" />
+ <path
+ android:name="background2"
+ android:fill="#80000000"
+ android:pathData="M 200,200 l 200,0 l 0, 200 l -200, 0 z" />
+ </group>
+ <group
+ android:name="translateToCenterGroup"
+ android:translateX="50.0"
+ android:translateY="90.0" >
+ <path
+ android:name="twoLines"
+ android:pathData="M 0,0 v 100 M 0,0 h 100"
+ android:stroke="#FFFF0000"
+ android:strokeWidth="20" />
+
+ <group
+ android:name="rotationGroup"
+ android:pivotX="0.0"
+ android:pivotY="0.0"
+ android:rotation="-45.0" >
+ <path
+ android:name="twoLines1"
+ android:pathData="M 0,0 v 100 M 0,0 h 100"
+ android:stroke="#FF00FF00"
+ android:strokeWidth="20" />
+
+ <group
+ android:name="translateGroup"
+ android:translateX="130.0"
+ android:translateY="160.0" >
+ <group android:name="scaleGroup" >
+ <path
+ android:name="twoLines2"
+ android:pathData="M 0,0 v 100 M 0,0 h 100"
+ android:stroke="#FF0000FF"
+ android:strokeWidth="20" />
+ </group>
+ </group>
+ </group>
+ </group>
+
+</vector>
\ No newline at end of file
diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable23.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable23.xml
new file mode 100644
index 0000000..52acd7a
--- /dev/null
+++ b/tests/VectorDrawableTest/res/drawable/vector_drawable23.xml
@@ -0,0 +1,86 @@
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <size
+ android:height="64dp"
+ android:width="64dp" />
+
+ <viewport
+ android:viewportHeight="400"
+ android:viewportWidth="400" />
+
+ <group android:name="backgroundGroup" >
+ <path
+ android:name="background1"
+ android:fill="#80000000"
+ android:pathData="M 0,0 l 200,0 l 0, 200 l -200, 0 z" />
+ <path
+ android:name="background2"
+ android:fill="#80000000"
+ android:pathData="M 200,200 l 200,0 l 0, 200 l -200, 0 z" />
+ </group>
+ <group
+ android:name="translateToCenterGroup"
+ android:translateX="50.0"
+ android:translateY="90.0" >
+ <path
+ android:name="twoLines"
+ android:pathData="@string/twoLinePathData"
+ android:stroke="#FFFF0000"
+ android:strokeWidth="20" />
+
+ <group
+ android:name="rotationGroup"
+ android:pivotX="0.0"
+ android:pivotY="0.0"
+ android:rotation="-45.0" >
+ <path
+ android:name="twoLines1"
+ android:pathData="@string/twoLinePathData"
+ android:stroke="#FF00FF00"
+ android:strokeWidth="20" />
+
+ <group
+ android:name="translateGroup"
+ android:translateX="130.0"
+ android:translateY="160.0" >
+ <group android:name="scaleGroup" >
+ <path
+ android:name="twoLines3"
+ android:pathData="@string/twoLinePathData"
+ android:stroke="#FF0000FF"
+ android:strokeWidth="20" />
+ </group>
+ </group>
+
+ <group
+ android:name="translateGroupHalf"
+ android:translateX="65.0"
+ android:translateY="80.0" >
+ <group android:name="scaleGroup" >
+ <path
+ android:name="twoLines2"
+ android:pathData="@string/twoLinePathData"
+ android:fill="?android:attr/colorForeground"
+ android:stroke="?android:attr/colorForeground"
+ android:strokeWidth="20" />
+ </group>
+ </group>
+ </group>
+ </group>
+
+</vector>
\ No newline at end of file
diff --git a/tests/VectorDrawableTest/res/values/strings.xml b/tests/VectorDrawableTest/res/values/strings.xml
index 64163c2..b49a1aa 100644
--- a/tests/VectorDrawableTest/res/values/strings.xml
+++ b/tests/VectorDrawableTest/res/values/strings.xml
@@ -15,4 +15,5 @@
-->
<resources>
+ <string name="twoLinePathData" >"M 0,0 v 100 M 0,0 h 100"</string>
</resources>
diff --git a/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorDrawablePerformance.java b/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorDrawablePerformance.java
index e0624e5..c2a5e6b 100644
--- a/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorDrawablePerformance.java
+++ b/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorDrawablePerformance.java
@@ -17,11 +17,11 @@
import android.content.res.Resources;
import android.graphics.drawable.VectorDrawable;
import android.os.Bundle;
-import android.view.View;
import android.widget.TextView;
import android.widget.Button;
import android.widget.GridLayout;
import android.widget.ScrollView;
+
import java.text.DecimalFormat;
@SuppressWarnings({"UnusedDeclaration"})
@@ -48,7 +48,9 @@
R.drawable.vector_drawable18,
R.drawable.vector_drawable19,
R.drawable.vector_drawable20,
- R.drawable.vector_drawable21
+ R.drawable.vector_drawable21,
+ R.drawable.vector_drawable22,
+ R.drawable.vector_drawable23
};
@Override