1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.wallpaper.livepicker; 18 19 import android.app.Activity; 20 import android.app.WallpaperManager; 21 import android.app.WallpaperInfo; 22 import android.app.Dialog; 23 import android.service.wallpaper.IWallpaperConnection; 24 import android.service.wallpaper.IWallpaperService; 25 import android.service.wallpaper.IWallpaperEngine; 26 import android.service.wallpaper.WallpaperSettingsActivity; 27 import android.content.ServiceConnection; 28 import android.content.Intent; 29 import android.content.Context; 30 import android.content.ComponentName; 31 import android.os.RemoteException; 32 import android.os.IBinder; 33 import android.os.ParcelFileDescriptor; 34 import android.os.Bundle; 35 import android.view.MotionEvent; 36 import android.view.View; 37 import android.view.WindowManager; 38 import android.view.ViewGroup; 39 import android.view.Window; 40 import android.view.LayoutInflater; 41 import android.util.Log; 42 import android.widget.TextView; 43 44 public class LiveWallpaperPreview extends Activity { 45 static final String EXTRA_LIVE_WALLPAPER_INTENT = "android.live_wallpaper.intent"; 46 static final String EXTRA_LIVE_WALLPAPER_SETTINGS = "android.live_wallpaper.settings"; 47 static final String EXTRA_LIVE_WALLPAPER_PACKAGE = "android.live_wallpaper.package"; 48 49 private static final String LOG_TAG = "LiveWallpaperPreview"; 50 51 private WallpaperManager mWallpaperManager; 52 private WallpaperConnection mWallpaperConnection; 53 54 private String mSettings; 55 private String mPackageName; 56 private Intent mWallpaperIntent; 57 private View mView; 58 private Dialog mDialog; 59 60 static void showPreview(Activity activity, int code, Intent intent, WallpaperInfo info) { 61 Intent preview = new Intent(activity, LiveWallpaperPreview.class); 62 preview.putExtra(EXTRA_LIVE_WALLPAPER_INTENT, intent); 63 preview.putExtra(EXTRA_LIVE_WALLPAPER_SETTINGS, info.getSettingsActivity()); 64 preview.putExtra(EXTRA_LIVE_WALLPAPER_PACKAGE, info.getPackageName()); 65 activity.startActivityForResult(preview, code); 66 } 67 68 @Override 69 protected void onCreate(Bundle savedInstanceState) { 70 super.onCreate(savedInstanceState); 71 72 Bundle extras = getIntent().getExtras(); 73 mWallpaperIntent = (Intent) extras.get(EXTRA_LIVE_WALLPAPER_INTENT); 74 if (mWallpaperIntent == null) { 75 setResult(RESULT_CANCELED); 76 finish(); 77 } 78 79 setContentView(R.layout.live_wallpaper_preview); 80 mView = findViewById(R.id.configure); 81 82 mSettings = extras.getString(EXTRA_LIVE_WALLPAPER_SETTINGS); 83 mPackageName = extras.getString(EXTRA_LIVE_WALLPAPER_PACKAGE); 84 if (mSettings == null) { 85 mView.setVisibility(View.GONE); 86 } 87 88 mWallpaperManager = WallpaperManager.getInstance(this); 89 90 mWallpaperConnection = new WallpaperConnection(mWallpaperIntent); 91 } 92 93 public void setLiveWallpaper(View v) { 94 try { 95 mWallpaperManager.getIWallpaperManager().setWallpaperComponent( 96 mWallpaperIntent.getComponent()); 97 mWallpaperManager.setWallpaperOffsetSteps(0.5f, 0.0f); 98 mWallpaperManager.setWallpaperOffsets(v.getRootView().getWindowToken(), 0.5f, 0.0f); 99 setResult(RESULT_OK); 100 } catch (RemoteException e) { 101 // do nothing 102 } catch (RuntimeException e) { 103 Log.w(LOG_TAG, "Failure setting wallpaper", e); 104 } 105 finish(); 106 } 107 108 @SuppressWarnings({"UnusedDeclaration"}) 109 public void configureLiveWallpaper(View v) { 110 Intent intent = new Intent(); 111 intent.setComponent(new ComponentName(mPackageName, mSettings)); 112 intent.putExtra(WallpaperSettingsActivity.EXTRA_PREVIEW_MODE, true); 113 startActivity(intent); 114 } 115 116 @Override 117 public void onResume() { 118 super.onResume(); 119 if (mWallpaperConnection != null && mWallpaperConnection.mEngine != null) { 120 try { 121 mWallpaperConnection.mEngine.setVisibility(true); 122 } catch (RemoteException e) { 123 // Ignore 124 } 125 } 126 } 127 128 @Override 129 public void onPause() { 130 super.onPause(); 131 if (mWallpaperConnection != null && mWallpaperConnection.mEngine != null) { 132 try { 133 mWallpaperConnection.mEngine.setVisibility(false); 134 } catch (RemoteException e) { 135 // Ignore 136 } 137 } 138 } 139 140 @Override 141 public void onAttachedToWindow() { 142 super.onAttachedToWindow(); 143 144 showLoading(); 145 146 mView.post(new Runnable() { 147 public void run() { 148 if (!mWallpaperConnection.connect()) { 149 mWallpaperConnection = null; 150 } 151 } 152 }); 153 } 154 155 private void showLoading() { 156 LayoutInflater inflater = LayoutInflater.from(this); 157 TextView content = (TextView) inflater.inflate(R.layout.live_wallpaper_loading, null); 158 159 mDialog = new Dialog(this, android.R.style.Theme_Black); 160 161 Window window = mDialog.getWindow(); 162 WindowManager.LayoutParams lp = window.getAttributes(); 163 164 lp.width = WindowManager.LayoutParams.MATCH_PARENT; 165 lp.height = WindowManager.LayoutParams.MATCH_PARENT; 166 window.setType(WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA); 167 168 mDialog.setContentView(content, new ViewGroup.LayoutParams( 169 ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT 170 )); 171 mDialog.show(); 172 } 173 174 @Override 175 public void onDetachedFromWindow() { 176 super.onDetachedFromWindow(); 177 178 if (mDialog != null) mDialog.dismiss(); 179 180 if (mWallpaperConnection != null) { 181 mWallpaperConnection.disconnect(); 182 } 183 mWallpaperConnection = null; 184 } 185 186 @Override 187 public boolean dispatchTouchEvent(MotionEvent ev) { 188 if (mWallpaperConnection != null && mWallpaperConnection.mEngine != null) { 189 MotionEvent dup = MotionEvent.obtainNoHistory(ev); 190 try { 191 mWallpaperConnection.mEngine.dispatchPointer(dup); 192 } catch (RemoteException e) { 193 } 194 } 195 196 if (ev.getAction() == MotionEvent.ACTION_DOWN) { 197 onUserInteraction(); 198 } 199 if (getWindow().superDispatchTouchEvent(ev)) { 200 return true; 201 } 202 return onTouchEvent(ev); 203 } 204 205 class WallpaperConnection extends IWallpaperConnection.Stub implements ServiceConnection { 206 final Intent mIntent; 207 IWallpaperService mService; 208 IWallpaperEngine mEngine; 209 boolean mConnected; 210 211 WallpaperConnection(Intent intent) { 212 mIntent = intent; 213 } 214 215 public boolean connect() { 216 synchronized (this) { 217 if (!bindService(mIntent, this, Context.BIND_AUTO_CREATE)) { 218 return false; 219 } 220 221 mConnected = true; 222 return true; 223 } 224 } 225 226 public void disconnect() { 227 synchronized (this) { 228 mConnected = false; 229 if (mEngine != null) { 230 try { 231 mEngine.destroy(); 232 } catch (RemoteException e) { 233 // Ignore 234 } 235 mEngine = null; 236 } 237 unbindService(this); 238 mService = null; 239 } 240 } 241 242 public void onServiceConnected(ComponentName name, IBinder service) { 243 if (mWallpaperConnection == this) { 244 mService = IWallpaperService.Stub.asInterface(service); 245 try { 246 final View view = mView; 247 final View root = view.getRootView(); 248 mService.attach(this, view.getWindowToken(), 249 WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY, 250 true, root.getWidth(), root.getHeight()); 251 } catch (RemoteException e) { 252 Log.w(LOG_TAG, "Failed attaching wallpaper; clearing", e); 253 } 254 } 255 } 256 257 public void onServiceDisconnected(ComponentName name) { 258 mService = null; 259 mEngine = null; 260 if (mWallpaperConnection == this) { 261 Log.w(LOG_TAG, "Wallpaper service gone: " + name); 262 } 263 } 264 265 public void attachEngine(IWallpaperEngine engine) { 266 synchronized (this) { 267 if (mConnected) { 268 mEngine = engine; 269 try { 270 engine.setVisibility(true); 271 } catch (RemoteException e) { 272 // Ignore 273 } 274 } else { 275 try { 276 engine.destroy(); 277 } catch (RemoteException e) { 278 // Ignore 279 } 280 } 281 } 282 } 283 284 public ParcelFileDescriptor setWallpaper(String name) { 285 return null; 286 } 287 } 288 } 289