[frameworks/base] support wfd sink for box version1.0

This commit is contained in:
Firefly
2016-02-03 10:10:55 +08:00
committed by cjp
parent 9cd14fc2ef
commit 89f7b50ba3
15 changed files with 275 additions and 21 deletions

View File

@ -24,6 +24,7 @@ import android.os.Handler;
import android.util.SparseArray;
import android.view.Display;
import android.view.Surface;
import android.util.Log;
import java.util.ArrayList;
@ -238,6 +239,7 @@ public final class DisplayManager {
public DisplayManager(Context context) {
mContext = context;
mGlobal = DisplayManagerGlobal.getInstance();
//Log.e(TAG, "DisplayManager: mGlobal=" + mGlobal);
}
/**
@ -321,10 +323,10 @@ public final class DisplayManager {
}
private Display getOrCreateDisplayLocked(int displayId, boolean assumeValid) {
//Log.d(TAG, "getOrCreateDisplayLocked: displayId=" + displayId);
Display display = mDisplays.get(displayId);
if (display == null) {
display = mGlobal.getCompatibleDisplay(displayId,
mContext.getDisplayAdjustments(displayId));
display = mGlobal.getCompatibleDisplay(displayId, mContext.getDisplayAdjustments(displayId));
if (display != null) {
mDisplays.put(displayId, display);
}
@ -479,6 +481,17 @@ public final class DisplayManager {
return createVirtualDisplay(name, width, height, densityDpi, surface, flags, null, null);
}
/**
* Judge the wfp p2p CONNECT status(add by szc).
*
* @return The current wfd p2p CONNECT status.
* @hide
*/
public boolean isWfdConnect() {
return mGlobal.isWfdConnect();
}
/**
* Creates a virtual display.
* <p>

View File

@ -45,7 +45,7 @@ import java.util.ArrayList;
*/
public final class DisplayManagerGlobal {
private static final String TAG = "DisplayManager";
private static final boolean DEBUG = false;
private static final boolean DEBUG = true;
// True if display info and display ids should be cached.
//
@ -90,6 +90,7 @@ public final class DisplayManagerGlobal {
synchronized (DisplayManagerGlobal.class) {
if (sInstance == null) {
IBinder b = ServiceManager.getService(Context.DISPLAY_SERVICE);
//Log.e(TAG, "getInstance: b=" + b);
if (b != null) {
sInstance = new DisplayManagerGlobal(IDisplayManager.Stub.asInterface(b));
}
@ -108,6 +109,7 @@ public final class DisplayManagerGlobal {
public DisplayInfo getDisplayInfo(int displayId) {
try {
synchronized (mLock) {
//Log.d(TAG, "getDisplayInfo");
DisplayInfo info;
if (USE_CACHE) {
info = mDisplayInfoCache.get(displayId);
@ -370,6 +372,16 @@ public final class DisplayManagerGlobal {
}
}
public boolean isWfdConnect() {
try {
return mDm.isWfdConnect();
} catch (RemoteException ex) {
Log.e(TAG, "Failed to get Wifi display status.", ex);
return false;
}
}
public VirtualDisplay createVirtualDisplay(Context context, MediaProjection projection,
String name, int width, int height, int densityDpi, Surface surface, int flags,
VirtualDisplay.Callback callback, Handler handler) {

View File

@ -59,6 +59,8 @@ interface IDisplayManager {
// No permissions required.
WifiDisplayStatus getWifiDisplayStatus();
boolean isWfdConnect();
// Requires CAPTURE_VIDEO_OUTPUT, CAPTURE_SECURE_VIDEO_OUTPUT, or an appropriate
// MediaProjection token for certain combinations of flags.
int createVirtualDisplay(in IVirtualDisplayCallback callback,

View File

@ -74,6 +74,9 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import android.view.View.OnFocusChangeListener;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
@ -103,6 +106,8 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
private boolean mResolvingHome = false;
private int mProfileSwitchMessageId = -1;
private Intent mIntent;
private Context mAppContext;
private UsageStatsManager mUsm;
private Map<String, UsageStats> mStats;
@ -187,6 +192,7 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
}
setSafeForwardingMode(true);
mAppContext = getApplication().getBaseContext();
onCreate(savedInstanceState, intent, null, 0, null, null, true);
}
@ -259,6 +265,7 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
setContentView(layoutId);
mListView = (ListView) findViewById(R.id.resolver_list);
mListView.setAdapter(mAdapter);
mListView.setSelector(this.getDrawable(com.android.internal.R.drawable.list_selector_background));
mListView.setOnItemClickListener(this);
mListView.setOnItemLongClickListener(new ItemLongClickListener());
@ -322,6 +329,31 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
buttonLayout.setVisibility(View.VISIBLE);
mAlwaysButton = (Button) buttonLayout.findViewById(R.id.button_always);
mOnceButton = (Button) buttonLayout.findViewById(R.id.button_once);
mAlwaysButton.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View arg0, boolean hasFocus) {
// TODO Auto-generated method stub
if (hasFocus) {
mAlwaysButton.setBackground(mAppContext.getDrawable(com.android.internal.R.drawable.btn_default));
} else {
mAlwaysButton.setBackground(null);
}
}
});
mOnceButton.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View arg0, boolean hasFocus) {
// TODO Auto-generated method stub
if (hasFocus) {
mOnceButton.setBackground(mAppContext.getDrawable(com.android.internal.R.drawable.btn_default));
} else {
mOnceButton.setBackground(null);
}
}
});
} else {
mAlwaysUseOption = false;
}

View File

@ -1184,7 +1184,7 @@ public class StateMachine {
/** @see StateMachine#transitionTo(IState) */
private final void transitionTo(IState destState) {
mDestState = (State) destState;
if (mDbg) mSm.log("transitionTo: destState=" + mDestState.getName());
mSm.log("transitionTo: destState=" + mDestState.getName());
}
/** @see StateMachine#deferMessage(Message) */

View File

@ -16,17 +16,17 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_window_focused="false" android:state_enabled="true"
android:drawable="@drawable/btn_default_normal" />
android:drawable="@drawable/btn_default_selected" />
<item android:state_window_focused="false" android:state_enabled="false"
android:drawable="@drawable/btn_default_normal_disable" />
android:drawable="@drawable/btn_default_selected" />
<item android:state_pressed="true"
android:drawable="@drawable/btn_default_pressed" />
<item android:state_focused="true" android:state_enabled="true"
android:drawable="@drawable/btn_default_selected" />
<item android:state_enabled="true"
android:drawable="@drawable/btn_default_normal" />
android:drawable="@drawable/btn_default_selected" />
<item android:state_focused="true"
android:drawable="@drawable/btn_default_normal_disable_focused" />
android:drawable="@drawable/btn_default_selected" />
<item
android:drawable="@drawable/btn_default_normal_disable" />
android:drawable="@drawable/btn_default_selected" />
</selector>

View File

@ -16,5 +16,5 @@
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?attr/colorControlHighlight">
<item android:drawable="@drawable/btn_default_mtrl_shape" />
<item android:drawable="@drawable/btn_default" />
</ripple>

View File

@ -16,7 +16,7 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true" android:state_checked="true" android:drawable="@drawable/list_selector_background_focused_selected" />
<item android:state_focused="false" android:state_checked="true" android:drawable="@drawable/list_selector_background_selected" />
<item android:state_focused="true" android:state_checked="true" android:drawable="@drawable/list_selector_background_focus" />
<item android:state_focused="false" android:state_checked="true" android:drawable="@drawable/list_selector_background_focus" />
</selector>

View File

@ -75,6 +75,7 @@
<item>@drawable/btn_default_disabled_holo_dark</item>
<item>@drawable/btn_default_disabled_focused_holo_light</item>
<item>@drawable/btn_default_disabled_focused_holo_dark</item>
<item>@drawable/btn_default</item> <!-- wgh -->
<item>@drawable/btn_default_holo_dark</item>
<item>@drawable/btn_default_holo_light</item>
<item>@drawable/btn_star_off_normal_holo_light</item>

View File

@ -1696,7 +1696,6 @@ class AlarmManagerService extends SystemService {
if (localLOGV) {
Slog.v(TAG, "sending alarm " + alarm);
}
mBackgroundIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
alarm.operation.send(getContext(), 0,
mBackgroundIntent.putExtra(
Intent.EXTRA_ALARM_COUNT, alarm.count),

View File

@ -1239,6 +1239,13 @@ public final class DisplayManagerService extends SystemService {
}
}
public boolean isWfdConnect() {
if (mWifiDisplayAdapter != null) {
return mWifiDisplayAdapter.isWfdConnect();
}
return false;
}
@Override // Binder call
public void pauseWifiDisplay() {
mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,

View File

@ -62,7 +62,7 @@ import libcore.util.Objects;
final class WifiDisplayAdapter extends DisplayAdapter {
private static final String TAG = "WifiDisplayAdapter";
private static final boolean DEBUG = false;
private static final boolean DEBUG = true;
private static final int MSG_SEND_STATUS_CHANGE_BROADCAST = 1;
@ -101,6 +101,12 @@ final class WifiDisplayAdapter extends DisplayAdapter {
com.android.internal.R.bool.config_wifiDisplaySupportsProtectedBuffers);
}
public boolean isWfdConnect() {
if (mDisplayController != null)
return mDisplayController.isWfdConnect();
return false;
}
@Override
public void dumpLocked(PrintWriter pw) {
super.dumpLocked(pw);

View File

@ -56,6 +56,22 @@ import java.util.Enumeration;
import libcore.util.Objects;
import android.net.wifi.p2p.WifiP2pInfo;
import android.net.wifi.p2p.WifiP2pManager.ConnectionInfoListener;
import android.os.SystemProperties;
import java.util.ArrayList;
import java.util.Collection;
import android.widget.Toast;
import android.os.Looper;
import android.os.PowerManager;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
/**
* Manages all of the various asynchronous interactions with the {@link WifiP2pManager}
* on behalf of {@link WifiDisplayAdapter}.
@ -70,7 +86,7 @@ import libcore.util.Objects;
*/
final class WifiDisplayController implements DumpUtils.Dump {
private static final String TAG = "WifiDisplayController";
private static final boolean DEBUG = false;
private static final boolean DEBUG = true;
private static final int DEFAULT_CONTROL_PORT = 7236;
private static final int MAX_THROUGHPUT = 50;
@ -78,6 +94,13 @@ final class WifiDisplayController implements DumpUtils.Dump {
private static final int RTSP_TIMEOUT_SECONDS = 30;
private static final int RTSP_TIMEOUT_SECONDS_CERT_MODE = 120;
private static final int WIFI_DISPLAY_DISABLE = 1;
private static final int WIFI_DISPLAY_STARTING = 2;
private static final int WIFI_DISPLAY_ENABLED = 3;
private static final int WIFI_DISPLAY_CONNECTED = 3;
private static File DDR_FREQ = new File("/dev/video_state");
// We repeatedly issue calls to discover peers every so often for a few reasons.
// 1. The initial request may fail and need to retried.
// 2. Discovery will self-abort after any group is initiated, which may not necessarily
@ -102,6 +125,13 @@ final class WifiDisplayController implements DumpUtils.Dump {
private boolean mWfdEnabled;
private boolean mWfdEnabling;
private NetworkInfo mNetworkInfo;
private WifiP2pDevice mP2pDeviceInfo;
private WifiP2pGroup mP2pGroupInfo;
private boolean mWifiWFDServicerOn=false;
private boolean mWfdHavePort;
private boolean mWfdState;
private PowerManager.WakeLock mWakeLock;
private final ArrayList<WifiP2pDevice> mAvailableWifiDisplayPeers =
new ArrayList<WifiP2pDevice>();
@ -165,6 +195,7 @@ final class WifiDisplayController implements DumpUtils.Dump {
mHandler = handler;
mListener = listener;
mWifiP2pManager = (WifiP2pManager)context.getSystemService(Context.WIFI_P2P_SERVICE);
mWifiP2pChannel = mWifiP2pManager.initialize(context, handler.getLooper(), null);
@ -284,7 +315,16 @@ final class WifiDisplayController implements DumpUtils.Dump {
WifiP2pWfdInfo wfdInfo = new WifiP2pWfdInfo();
wfdInfo.setWfdEnabled(true);
wfdInfo.setDeviceType(WifiP2pWfdInfo.WFD_SOURCE);
//String boxString = android.os.SystemProperties.get("ro.target.product");
//boolean isBox = "box".equals(boxString);
if ("box".equals(SystemProperties.get("ro.target.product","tablet"))) {
Slog.d(TAG, "ro.target.product ======= box");
wfdInfo.setDeviceType(WifiP2pWfdInfo.PRIMARY_SINK);
} else {
Slog.d(TAG, "ro.target.product ======= tablet");
wfdInfo.setDeviceType(WifiP2pWfdInfo.WFD_SOURCE);
}
wfdInfo.setSessionAvailable(true);
wfdInfo.setControlPort(DEFAULT_CONTROL_PORT);
wfdInfo.setMaxThroughput(MAX_THROUGHPUT);
@ -444,7 +484,7 @@ final class WifiDisplayController implements DumpUtils.Dump {
Slog.d(TAG, " " + describeWifiP2pDevice(device));
}
if (isWifiDisplay(device)) {
if (isWifiDisplay(device) || isWifiDisplaySource(device)) {
mAvailableWifiDisplayPeers.add(device);
}
}
@ -814,9 +854,112 @@ final class WifiDisplayController implements DumpUtils.Dump {
requestPeers();
}
// gwl
private void setScreenLock(boolean on) {
if(mWakeLock == null) {
PowerManager pm = (PowerManager) mContext.getSystemService(mContext.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, TAG);
}
if (on) {
Slog.i(TAG," mWakeLock.acquire()");
mWakeLock.acquire();
} else {
if(mWakeLock.isHeld()) {
Slog.i(TAG," mWakeLock.release()");
mWakeLock.release();
}
mWakeLock = null;
}
}
private void handleWFDConnectionChanged(NetworkInfo networkInfo,WifiP2pDevice P2pDeviceInfo) {
mNetworkInfo = networkInfo;
mP2pDeviceInfo =P2pDeviceInfo;
Slog.d(TAG, "####onConnectionInfoAvailable(), mWfdEnabled networkInfo.isConnected() "+ mWfdEnabled + ", networkInfo.isConnected() " + networkInfo.isConnected());
if (mWfdEnabled && networkInfo.isConnected()) {
mWifiP2pManager.requestConnectionInfo(mWifiP2pChannel, new ConnectionInfoListener(){
@Override
public void onConnectionInfoAvailable(WifiP2pInfo info)
{
Slog.d(TAG,"####onConnectionInfoAvailable(),info = "+ info + ", mDesiredDevice=" + mDesiredDevice);
String command = "wfd:-s "+mP2pDeviceInfo.deviceAddress+":";
mWfdHavePort =false;
Slog.d(TAG,"####mP2pDeviceInfo.deviceAddress = "+mP2pDeviceInfo.deviceAddress);
for (WifiP2pDevice device : mAvailableWifiDisplayPeers) {
Slog.d(TAG,"####device = "+device);
if(device.deviceAddress.equals(mP2pDeviceInfo.deviceAddress))
{
mWfdHavePort =true;
command +=device.wfdInfo.getControlPort();
break;
}
}
if(mWfdHavePort ==false)
{
Slog.d(TAG,"######inited error mWfdHavePort is false" );
command += "7236";
//return ;
}
Slog.d(TAG,"###### inited setprop command "+command);
//szc
//wmLockRotation();
SystemProperties.set("ctl.start",command);
mWifiWFDServicerOn =true;
if (mDiscoverPeersInProgress) {
mHandler.removeCallbacks(mDiscoverPeers);
if (mDesiredDevice == null || mDesiredDevice == mConnectedDevice) {
Slog.i(TAG, "Stopping Wifi display scan.");
mDiscoverPeersInProgress = false;
stopPeerDiscovery();
handleScanFinished();
}
}
}
});
}
else{
Slog.d(TAG,"######mWifiWFDServicerOn =mWfdEnabled networkInfo.isConnected()"+mWifiWFDServicerOn + mWfdEnabled + networkInfo.isConnected());
if(mWifiWFDServicerOn==true)
{
// szc
//wmFreeRotation();
mWifiWFDServicerOn =false;
SystemProperties.set("ctl.stop","wfd");
if (mScanRequested && mWfdEnabled && mDesiredDevice == null) {
if (!mDiscoverPeersInProgress) {
Slog.i(TAG, "Starting Wifi display scan.");
mDiscoverPeersInProgress = true;
handleScanStarted();
tryDiscoverPeers();
}
}
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
Slog.d(TAG,"######mWifiWFDServicerOn restart####");
updateSettings();
}},2000);
}
}
}
// szc :judge the wfd connect state
public boolean isWfdConnect() {
return mWifiWFDServicerOn;
}
private void handleConnectionChanged(NetworkInfo networkInfo) {
mNetworkInfo = networkInfo;
if (mWfdEnabled && networkInfo.isConnected()) {
setScreenLock(true);
if (mDesiredDevice != null || mWifiDisplayCertMode) {
mWifiP2pManager.requestGroupInfo(mWifiP2pChannel, new GroupInfoListener() {
@Override
@ -876,6 +1019,7 @@ final class WifiDisplayController implements DumpUtils.Dump {
// Disconnect if we lost the network while connecting or connected to a display.
if (mConnectingDevice != null || mConnectedDevice != null) {
setScreenLock(false);
disconnect();
}
@ -1027,6 +1171,18 @@ final class WifiDisplayController implements DumpUtils.Dump {
return DEFAULT_CONTROL_PORT;
}
private static boolean isWifiDisplaySource(WifiP2pDevice device) {
return device.wfdInfo != null
&& device.wfdInfo.isWfdEnabled()
&& isSourceDeviceType(device.wfdInfo.getDeviceType());
}
private static boolean isSourceDeviceType(int deviceType) {
return deviceType == WifiP2pWfdInfo.WFD_SOURCE
|| deviceType == WifiP2pWfdInfo.SOURCE_OR_PRIMARY_SINK;
}
private static boolean isWifiDisplay(WifiP2pDevice device) {
return device.wfdInfo != null
&& device.wfdInfo.isWfdEnabled()
@ -1076,12 +1232,20 @@ final class WifiDisplayController implements DumpUtils.Dump {
} else if (action.equals(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION)) {
NetworkInfo networkInfo = (NetworkInfo)intent.getParcelableExtra(
WifiP2pManager.EXTRA_NETWORK_INFO);
WifiP2pDevice connectDevice = (WifiP2pDevice) intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE);
if (DEBUG) {
Slog.d(TAG, "Received WIFI_P2P_CONNECTION_CHANGED_ACTION: networkInfo="
+ networkInfo);
}
handleConnectionChanged(networkInfo);
if (mDesiredDevice == null) {
Slog.d(TAG, "mDesiredDevice == NULL, So it is a sink device");
handleWFDConnectionChanged(networkInfo, connectDevice);
} else {
Slog.d(TAG, "mDesiredDevice != NULL, So it is a source device");
}
} else if (action.equals(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION)) {
mThisDevice = (WifiP2pDevice) intent.getParcelableExtra(
WifiP2pManager.EXTRA_WIFI_P2P_DEVICE);

View File

@ -81,6 +81,8 @@ import java.io.PrintWriter;
import java.io.RandomAccessFile;
//--------end----------------
import android.hardware.display.DisplayManager;
import android.net.wifi.WifiManager;
import static android.os.PowerManagerInternal.WAKEFULNESS_ASLEEP;
import static android.os.PowerManagerInternal.WAKEFULNESS_AWAKE;
@ -104,6 +106,7 @@ public final class PowerManagerService extends SystemService
private static final int MSG_SANDMAN = 2;
// Message: Sent when the screen brightness boost expires.
private static final int MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT = 3;
private static final int MSG_DISABLE_WIFI_FOR_WIFIP2P = 5;
// Dirty bit: mWakeLocks changed
private static final int DIRTY_WAKE_LOCKS = 1 << 0;
@ -462,6 +465,9 @@ public final class PowerManagerService extends SystemService
private static native void nativeCpuBoost(int duration);
private static native void nativeSetPerformanceMode(int mode);
private DisplayManager mDisplayManager;
private WifiManager mWifiManager;
public PowerManagerService(Context context) {
super(context);
mContext = context;
@ -469,6 +475,7 @@ public final class PowerManagerService extends SystemService
Process.THREAD_PRIORITY_DISPLAY, false /*allowIo*/);
mHandlerThread.start();
mHandler = new PowerManagerHandler(mHandlerThread.getLooper());
mDisplayManager = (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE);
synchronized (mLock) {
mWakeLockSuspendBlocker = createSuspendBlockerLocked("PowerManagerService.WakeLocks");
@ -2844,6 +2851,11 @@ public final class PowerManagerService extends SystemService
case MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT:
handleScreenBrightnessBoostTimeout();
break;
case MSG_DISABLE_WIFI_FOR_WIFIP2P:
mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
mWifiManager.setWifiEnabled(false);
mWifiManager.setWifiEnabled(true);
break;
}
}
}
@ -3204,6 +3216,12 @@ public final class PowerManagerService extends SystemService
final int uid = Binder.getCallingUid();
final long ident = Binder.clearCallingIdentity();
try {
if (reason != PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN && reason != PowerManager.GO_TO_SLEEP_REASON_TIMEOUT) {
if (mDisplayManager.isWfdConnect()) {
mHandler.sendEmptyMessage(MSG_DISABLE_WIFI_FOR_WIFIP2P);
return;
}
}
goToSleepInternal(eventTime, reason, flags, uid);
} finally {
Binder.restoreCallingIdentity(ident);

View File

@ -321,6 +321,10 @@ public final class SystemServer {
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
// Display manager is needed to provide display metrics before package manager
// starts up.
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
// Power manager needs to be started early because other services need it.
// Native daemons may be watching for it to be registered so it must be ready
// to handle incoming binder calls immediately (including being able to verify
@ -331,10 +335,6 @@ public final class SystemServer {
// initialize power management features.
mActivityManagerService.initPowerManagement();
// Display manager is needed to provide display metrics before package manager
// starts up.
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
// We need the default display before we can initialize the package manager.
mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);