/*
* @(#)MediaThread.java 1.17 02/08/21
*
* Copyright (c) 1996-2002 Sun Microsystems, Inc. All rights reserved.
*/
package com.sun.media.util;
import com.sun.media.JMFSecurity;
import com.sun.media.JMFSecurityManager;
import com.sun.media.NetscapeSecurity;
import com.sun.media.JDK12Security;
import com.sun.media.IESecurity;
import java.lang.reflect.Method;
import java.lang.reflect.Constructor;
import java.security.*;
import com.ms.security.PermissionID;
import com.ms.security.PolicyEngine;
import com.sun.media.BasicPlayer; // $$$$ REMOVE
/**
* Note: In netscape, if the user doesn't give Thread priority, you
* will not be able to reduce the priority also. All threads
* will run under same priority.
/**
* A thread class where all JMF created threads should based on.
*/
public class MediaThread extends Thread {
private static ThreadGroup threadGroup;
static boolean securityPrivilege = true;
private static final boolean debug = false;
private static int controlPriority = Thread.MAX_PRIORITY - 1;
private static int audioPriority = Thread.MAX_PRIORITY - 5;
/* To be less than the Appletpriority */
private static int videoPriority = Thread.NORM_PRIORITY - 2;
private static int networkPriority = audioPriority + 1;
private static int videoNetworkPriority = networkPriority - 1;
// If you don't have threadgroup and thread permissions.
private static int defaultMaxPriority = 4;
static {
JMFSecurity jmfSecurity = null;
Method m[] = new Method[1];
Class cl[] = new Class[1];
Object args[][] = new Object[1][0];
try {
// If you dont get thread and threadgroup access,
// using default thread group (null), else
// use root thread group
jmfSecurity = JMFSecurityManager.getJMFSecurity();
if ( jmfSecurity != null ) {
if (jmfSecurity.getName().startsWith("jmf-security")) {
boolean haveBoth = true;
defaultMaxPriority = Thread.currentThread().getPriority();
try {
jmfSecurity.requestPermission(m, cl, args, JMFSecurity.THREAD);
m[0].invoke(cl[0], args[0]);
} catch (Throwable t) {
jmfSecurity.permissionFailureNotification(JMFSecurity.THREAD);
haveBoth = false;
}
if (haveBoth) {
defaultMaxPriority =
Thread.currentThread().getThreadGroup().getMaxPriority();
// System.out.println(" $$$ Now setting defaultMaxPriority as the current threads MAX priority which is " + defaultMaxPriority);
}
try {
jmfSecurity.requestPermission(m, cl, args, JMFSecurity.THREAD_GROUP);
m[0].invoke(cl[0], args[0]);
} catch (Throwable t) {
jmfSecurity.permissionFailureNotification(JMFSecurity.THREAD_GROUP);
haveBoth = false;
}
if (!haveBoth) {
throw new Exception("No thread and or threadgroup permission");
}
} else if (jmfSecurity.getName().startsWith("internet")) {
PolicyEngine.assertPermission(PermissionID.THREAD);
} else if (jmfSecurity.getName().startsWith("jdk12")) {
Constructor cons = jdk12Action.getCheckPermissionAction();
defaultMaxPriority = Thread.currentThread().getPriority();
jdk12.doPrivContextM.invoke(
jdk12.ac,
new Object[] {
cons.newInstance(
new Object[] {
JDK12Security.getThreadPermission()
}),
jdk12.getContextM.invoke(null, null)
});
defaultMaxPriority =
Thread.currentThread().getThreadGroup().getMaxPriority();
jdk12.doPrivContextM.invoke(
jdk12.ac,
new Object[] {
cons.newInstance(
new Object[] {
JDK12Security.getThreadGroupPermission()
}),
jdk12.getContextM.invoke(null, null)
});
} else if (jmfSecurity.getName().startsWith("default")) {
// TODO: even if class loader is not null
// we should check to see if the classes are signed
if (MediaThread.class.getClassLoader() != null) {
// jmf from server
throw new SecurityException();
}
}
}
} catch (Throwable e) {
// System.err.println("Permission to manipulate threads and/or thread groups not granted " + e + " : " + e.getMessage());
securityPrivilege=false;
// System.out.println("defaultMaxPriority is " + defaultMaxPriority);
// TODO: tweak these based on testing
controlPriority = defaultMaxPriority;
audioPriority = defaultMaxPriority;
videoPriority = defaultMaxPriority - 1;
networkPriority = defaultMaxPriority;
videoNetworkPriority = defaultMaxPriority;
// TODO: Do the right thing if permissions cannot be obtained.
// User should be notified via an event
}
if (securityPrivilege) {
threadGroup = getRootThreadGroup();
// System.out.println("threadGroup is " + threadGroup);
}
else {
threadGroup = null;
// System.out.println("threadGroup is null");
}
}
static private ThreadGroup getRootThreadGroup() {
ThreadGroup current = null;
try {
current = Thread.currentThread().getThreadGroup();
ThreadGroup g = current;
for (; g.getParent() != null; g = g.getParent());
// System.out.println("Root threadgroup is " + g);
return g;
} catch (Exception e) {
return null; // current
} catch (Error e) {
return null; // current;
}
}
public MediaThread() {
this("JMF thread");
}
public MediaThread(String name) {
super(threadGroup, name);
}
public MediaThread(Runnable r) {
this(r, "JMF thread");
}
public MediaThread(Runnable r, String name) {
super(threadGroup, r, name);
}
/**
* This should be used for Manager, events threads etc. -- the mechanism
* to maintain the players.
*/
public void useControlPriority() {
usePriority(controlPriority);
}
/**
* This should be used for threads handling the audio medium.
*/
public void useAudioPriority() {
usePriority(audioPriority);
}
/**
* This should be used for threads handling the video medium.
*/
public void useVideoPriority() {
usePriority(videoPriority);
}
/**
* This should be used for threads handling network packets. e.g. RTP
*/
public void useNetworkPriority() {
usePriority(networkPriority);
}
public void useVideoNetworkPriority(){
usePriority(videoNetworkPriority);
}
public static int getControlPriority() {
return controlPriority;
}
public static int getAudioPriority() {
return audioPriority;
}
public static int getVideoPriority() {
return videoPriority;
}
public static int getNetworkPriority() {
return networkPriority;
}
public static int getVideoNetworkPriority() {
return videoNetworkPriority;
}
private void usePriority(int priority) {
try {
setPriority(priority);
} catch (Throwable t) {
}
if (debug) {
checkPriority("priority",
priority,
securityPrivilege, getPriority());
}
}
private void checkPriority(String name, int ask, boolean priv, int got) {
if (ask != got) {
System.out.println("MediaThread: " + name + " privilege? " + priv + " ask pri: " + ask + " got pri: " + got);
}
}
}
|