javauis/nokiauiapi_qt/javasrc/com/nokia/mid/ui/SoftNotificationImpl.java
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Mon, 04 Oct 2010 00:10:53 +0300
changeset 79 2f468c1958d0
permissions -rw-r--r--
Revision: v2.2.15 Kit: 201039

/*
 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of "Eclipse Public License v1.0"
 * which accompanies this distribution, and is available
 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
 *
 * Initial Contributors:
 * Nokia Corporation - initial contribution.
 *
 * Contributors:
 *
 * Description:
 *
 */

package com.nokia.mid.ui;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.OutputStream;

import org.eclipse.swt.internal.extension.DisplayExtension;
import org.eclipse.swt.widgets.Internal_PackageSupport;

import com.nokia.mid.ui.internal.OS;
import com.nokia.mid.ui.SoftNotificationException;
import com.nokia.mid.ui.SoftNotificationListener;
import com.nokia.mj.impl.fileutils.FileUtility;
import com.nokia.mj.impl.rt.support.Finalizer;
import com.nokia.mj.impl.rt.support.ApplicationInfo;

/**
 * SoftNotificationImpl implements the functionality specified in
 * com.nokia.mid.ui.SoftNotification class.
 */
final class SoftNotificationImpl extends com.nokia.mid.ui.SoftNotification {

	// Native CSoftNotification handle
	private int iSoftNotificationHandle = 0;

	// Observer of this class set by the API user. An array is used to allow
	// listener synchronization.
	private SoftNotificationListener[] iListener;

	// Listener event when user accepted notification
	private final static int EVENT_ACCEPT = 1;

	// Listener event when user dismissed notification
	private final static int EVENT_DISMISS = 2;

	// Error message prefix for exceptions.
	private final static String ERROR_MESSAGE_PREFIX = "Failed to ";

	// The class will have native resources so register it for
	// finalization.
	private Finalizer mFinalizer;

	private int err;

	private int id;
	
	private int midletUid;

	/**
	 * Constructor. New instance with old identifier.
	 * 
	 * @param aNotificationId
	 *            Identification of previous soft notification.
	 */
	public SoftNotificationImpl(int aNotificationId) {
		initialize(aNotificationId);
	}

	/**
	 * Constructor. New instance.
	 */
	public SoftNotificationImpl() {
		initialize(0);
	}

	/**
	 * Initializes the instance.
	 * 
	 * @param aNotificationId
	 *            Id of the soft notification.
	 */
	protected void initialize(int aNotificationId) {
		final int iNotificationId = aNotificationId;
		iListener = new SoftNotificationListener[1];

		Runnable r = new Runnable() {
			public void run() {
				String uidString = ApplicationInfo.getInstance().getUid().toString();
				// removing "[" and "]" brackets
				uidString = uidString.substring(1,uidString.length()-1);
				// converting to decimal
				midletUid =(int)Long.parseLong(uidString,16);
				iSoftNotificationHandle = OS.createNativePeer(midletUid, iNotificationId,
						SoftNotificationImpl.this);
			}
		};
		// if display is created already, execute it in UI thread no matter
		// what thread it is called from. Otherwise assume LCDUI application is
		// called
		// and create a display. eSWT is not allowed to call before display
		// creation
		if (DisplayExtension.getDisplayInstance() != null) {
			DisplayExtension.getDisplayInstance().syncExec(r);
		} else {
			com.nokia.mj.impl.nokialcdui.LCDUIInvoker
					.eSWTUIThreadRunnerSyncExec(r);
		}

		if (iSoftNotificationHandle <= 0) {
			throw new OutOfMemoryError();
		}

		mFinalizer = ((mFinalizer != null) ? mFinalizer : new Finalizer() {
			public void finalizeImpl() {
				close();
			}
		});
	}

	/**
	 * Called when the object is finalized by the garbage collector.
	 */
	public void close() {
		if (DisplayExtension.getDisplayInstance() != null) {
			Internal_PackageSupport.getDisplayInstance().syncExec(new Runnable() {
				public void run() {
					if (mFinalizer != null) {
						OS.destroy(iSoftNotificationHandle);
					}
					mFinalizer = null;
				}
			});
		}
	}

	/**
	 * Notification callback, called from the native side.
	 * 
	 * @param aEventArg
	 *            Occurred event.
	 */
	private void notificationCallback(int aEventArg) {
		// Synchronize the listener usage since the user may want to set it
		// to null during execution of this function.
		synchronized (iListener) {
			SoftNotificationListener listener = iListener[0];

			if (listener != null) {
				if (aEventArg == EVENT_ACCEPT) {
					listener.notificationSelected(this);
				} else if (aEventArg == EVENT_DISMISS) {
					listener.notificationDismissed(this);
				}
			}
		}
	}

	/**
	 * Checks the given error value. Throws SoftNotificationException if the
	 * given error value is other than NativeError.KErrNone.
	 * 
	 * @param aError
	 *            Error value to be checked.
	 * @param aErrorMessage
	 *            Message to be included in the exception.
	 */
	private final void checkError(int aError, String aErrorMessage)
			throws SoftNotificationException {
		if (aError != 0) {
			throw new SoftNotificationException(ERROR_MESSAGE_PREFIX
					+ aErrorMessage, aError);
		}
	}

	// Functions from the base class.

	/**
	 * See class SoftNotification for comments
	 */
	public int getId() {
		if (DisplayExtension.getDisplayInstance() != null) {
			Internal_PackageSupport.getDisplayInstance().syncExec(
					new Runnable() {
						public void run() {
							id = 0;
							id = OS.getId(iSoftNotificationHandle);
						}
					});
		}
		return id;
	}

	/**
	 * See class SoftNotification for comments
	 */
	public void post() throws SoftNotificationException {
		if (DisplayExtension.getDisplayInstance() != null) {
			Internal_PackageSupport.getDisplayInstance().syncExec(
					new Runnable() {
						public void run() {
							err = 0;
							err = OS
									.showSoftNotification(iSoftNotificationHandle);
						}
					});
		}
		checkError(err, "add soft notification");
	}

	/**
	 * See class SoftNotification for comments
	 */
	public void remove() throws SoftNotificationException {
		if (DisplayExtension.getDisplayInstance() != null) {
			Internal_PackageSupport.getDisplayInstance().syncExec(
					new Runnable() {
						public void run() {
							err = 0;
							err = OS
									.removeSoftNotification(iSoftNotificationHandle);
						}
					});
		}
		checkError(err, "remove notification");
	}

	/**
	 * See class SoftNotification for comments
	 */
	public void setListener(SoftNotificationListener aListener) {
		// Synchronize the listener setting since the user may set it
		// to null during it is used elsewhere in this class.
		synchronized (iListener) {
			iListener[0] = aListener;
		}
	}

	/**
	 * See class SoftNotification for comments
	 */
	public void setText(String aPrimaryText, String aSecondaryText)
			throws SoftNotificationException {
		final String iPrimaryText = aPrimaryText;
		final String iSecondaryText = aSecondaryText;

		if (DisplayExtension.getDisplayInstance() != null) {
			Internal_PackageSupport.getDisplayInstance().syncExec(
					new Runnable() {
						public void run() {
							err = 0;
							err = OS.setText(iSoftNotificationHandle,
									iPrimaryText == null ? "" : iPrimaryText,
									iSecondaryText == null ? ""
											: iSecondaryText);
						}
					});
		}
		checkError(err, "set note text");
	}

	/**
	 * See class SoftNotification for comments
	 */
	public void setSoftkeyLabels(String aSoftkey1Label, String aSoftkey2Label)
			throws SoftNotificationException {
		int err = 0;
		checkError(err, "set softkeys");
	}

	private String stringReplace(String source, String searchStr,
			String replacementStr) {
		StringBuffer strBuffer = new StringBuffer();
		int pos = source.indexOf(searchStr);

		while (pos != -1) {
			strBuffer.append(source.substring(0, pos)).append(replacementStr);
			source = source.substring(pos + searchStr.length());
			pos = source.indexOf(searchStr);
		}
		strBuffer.append(source);
		return strBuffer.toString();
	}

	/**
	 * See class SoftNotification for comments
	 */
	public void setImage(byte[] aImageData) throws SoftNotificationException {
		if (aImageData != null) {
			final byte[] iImageData = aImageData;
			if (DisplayExtension.getDisplayInstance() != null) {
				Internal_PackageSupport.getDisplayInstance().syncExec(
						new Runnable() {
							public void run() {
								err = 0;
								String imagePath = "";
								try {
									String directoryPath = ApplicationInfo
											.getInstance().getRootPath();
									// Replace "\private\102033e6\apps" with
									// "resource\apps\java"
									directoryPath = stringReplace(
											directoryPath, "private", "public");
									directoryPath = directoryPath
											+ "softnotification\\"
											+ midletUid + "_"
											+ getId();
									String imageName = midletUid
											+ "_" + getId();
									FileUtility target = new FileUtility(
											directoryPath);
									if (!target.exists()) {
										target.mkdirs();
									}
									target = new FileUtility(directoryPath
											+ "\\" + imageName);
									if (!target.exists()) {
										target.createNewFile();
									}
									OutputStream fos = target
											.openOutputStream();
									ByteArrayInputStream in = new ByteArrayInputStream(
											iImageData);
									byte[] buf = new byte[1024];
									int len;
									while ((len = in.read(buf)) > 0) {
										fos.write(buf, 0, len);
									}
									in.close();
									fos.close();
									target = null;
									imagePath = directoryPath + "\\"
											+ imageName;
								} catch (IOException ex) {
									ex.printStackTrace();
								} catch (Throwable t) {
									t.printStackTrace();
								}
								err = OS.setImagePath(iSoftNotificationHandle,
										imagePath);
							}
						});
			}
		}
		checkError(err, "set image");
	}
}